C++和预处理器宏陷阱

发布于 2024-08-31 00:30:44 字数 364 浏览 3 评论 0原文

你能看出下面的陈述有什么问题吗?

GCC 错误指出:

“类型名称”声明为返回数组的函数

#define MACRO(a) (a)[1]

class index {
public:
    typedef int index_type[2];
    const index_type& operator[](int i) const;
};

int k = 0;
int i = MACRO(index()[k]);

顺便说一句:我知道出了什么问题,我认为分享这是一件有趣的事情。非常感谢 litb,他对之前问题的解释有助于很快解决这个错误。

Can you figure out what is wrong with the statement below?

GCC error states:

'type name' declared as function returning array

#define MACRO(a) (a)[1]

class index {
public:
    typedef int index_type[2];
    const index_type& operator[](int i) const;
};

int k = 0;
int i = MACRO(index()[k]);

btw: I know what is wrong, I thought it was amusing thing to share. Many thanks to litb, his explanation of previous gotcha helped to solve this error pretty quickly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾城°AllureLove 2024-09-07 00:30:44

在展开的行中:

int i = (index()[k])[1];

(index()[k]) 被解释为强制转换表达式,声明一个返回索引长度 k 的数组的函数。至少,事情看起来就是这样。我不确定 gcc 如何有效地将 [1] 解释为表达式。

In the expanded line:

int i = (index()[k])[1];

(index()[k]) is interpreted as a cast expression, declaring a function that returns an array of length k of index. At least, that's what it looks like is happening. How gcc is manages to validly interpret the [1] as an expression, I'm not sure.

活泼老夫 2024-09-07 00:30:44

我的猜测是您的语法存在歧义。编译器可能会查看扩展的宏:

 int i = (index()[k])[1];

并认为 index 实际上是返回数组的非成员函数声明,而不是构造 type 的临时对象索引

但这只是一个猜测...如果您已经知道答案,请告诉我们:)

My guess would be there's an ambiguity in your syntax. The compiler might be looking at the expanded macro:

 int i = (index()[k])[1];

And thinking that index is actually a non-member function declaration that returns an array, rather than construction of a temporary object of type index.

But that's just a guess... if you know the answer already, please enlighten us :)

眼角的笑意。 2024-09-07 00:30:44

当您应用宏时,它会扩展为:

class index 
{
    // ...
    typedef int index_type[2];
    const index_type& operator[](int i)const;
    // ...
};

int k = 0;
int i = (index()[k])[1];

现在的问题(假设 index::operator[] 是公共的,并且从代码片段中看不出来)是 index::operator[] 的结果通过引用返回,并且您正在将 index() 对象构造为临时对象,因此,假设您的 index::operator[] 是按照我猜测您实现它的方式实现的(返回对成员对象的引用) ,index::operator[]的结果在返回后将立即无效(因为临时被破坏),因此您有未定义的行为。

When you apply your macro, it expands to:

class index 
{
    // ...
    typedef int index_type[2];
    const index_type& operator[](int i)const;
    // ...
};

int k = 0;
int i = (index()[k])[1];

Now the problem (assuming that index::operator[] is public, and it is non-obvious from your code snippet that it is) is that the result of index::operator[] is returned by reference, and you are constructing the index() object as a temporary, and so, assuming your index::operator[] is implemented how I'm guessing you've implemented it (returning a reference to a member object), the result of index::operator[] will be invalid immediately after it is returned (as the temporary is destructed), and so you have undefined behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文