分享
为什么问答平台  ›  专栏  ›  技术社区  ›  Anycorn

C++和预处理器宏抓取[复制] - C++ and preprocessor macro gotcha [duplicate]

  •  4
  • Anycorn  · 技术社区  · 1 周前

    这个问题已经有了答案:

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

    GCC错误状态:

    “type name”声明为函数返回数组

    #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,他对之前gotcha的解释帮助很快解决了这个错误。

    3 回复  |  直到 2 年前
        1
  •  4
  •   outis    8 年前

    在展开的行中:

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

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

        2
  •  2
  •   Dean Harding    8 年前

    我猜你的语法可能有歧义。编译器可能正在查看扩展宏:

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

    并且认为 index 实际上是返回数组的非成员函数声明,而不是 类型 指数 .

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

        3
  •  1
  •   Michael Aaron Safyan    8 年前

    当应用宏时,它将扩展到:

    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[]的结果在返回后立即无效(因为临时对象已被销毁),因此具有未定义的行为。