【问题标题】:Why this code didn't work for -m32?为什么此代码不适用于 -m32?
【发布时间】:2015-07-18 10:50:05
【问题描述】:
#include <stddef.h>

template<size_t N = sizeof(void*)> struct a;

template<> struct a<4> {
    enum { b };
};

template<> struct a<8> {
    template<int> struct b {};
};

enum { c, d };

int main() {
    a<>::b<c>d;
    d;
}

我有一段代码通过 gcc 成功编译为 x64 架构。但失败并出现-m32 错误:

$ g++ -m32 test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:16:12: warning: comparison between ‘enum a<4u>::<anonymous>’ and ‘enum<anonymous>’ [-Wenum-compare]
     a<>::b<c>d;
            ^
collect2: error: ld returned 1 exit status

这段代码有什么问题?

【问题讨论】:

    标签: c++ templates g++ 32bit-64bit


    【解决方案1】:

    您的代码是正确的。显然,因为警告只是警告。它指向这样一个事实,即比较涉及两个不相关的枚举,因此可能是不明智的。

    如果您对分析感兴趣:
    由于您正在为 x86-32 编译,sizeof(void*) 是 4。所以a&lt;&gt; 指的是a&lt;4&gt;,随后a&lt;4&gt;::b 指的是一个枚举器。

    所以表达式语句

    a<>::b<c>d;
    

    被解析为

    (a<>::b < c) > d;
    

    现在执行通常的算术转换,在此期间,使用整数提升规则将两个操作数提升为int。 [expr.rel]/2:

    通常的算术转换是在操作数上执行的 算术或枚举类型。 […]。 转换后的操作数必须具有相同的类型。

    (注意粗体部分,后面会保证。)[expr]/10:

    这种模式称为通常的算术转换, 定义如下:

    • 如果任一操作数属于范围枚举类型 (7.2),则不执行任何转换;如果另一个操作数不一样 类型,表达式格式不正确。
    • […关于浮点类型的要点…]
    • 否则,应在两个操作数上执行积分提升 (4.5)。那么以下规则应适用于 提升的操作数:
      • 如果两个操作数的类型相同,则无需进一步转换。
      • […]

    [conv.prom]/3 中介绍了枚举器的整体提升:

    其基础类型不是无作用域枚举类型的纯右值 固定(7.2)可以转换为第一个的prvalue 以下类型可以表示枚举的所有值 (即,在 bminbmax 范围内的值,如 7.2 所述): intunsigned intlong intunsigned long intlong long intunsigned long long int.

    两个操作数都提升为int后,表达式的结果为false(因为0不小于0)。

    然后将这个提升的结果与d 进行比较——这里,d 被提升为int,如上所述,而比较的结果——bool 类型——被提升为@ 987654342@ 也是。 [conv.prom]/6:

    bool 类型的纯右值可以转换为int 类型的纯右值,使用 false 变为 0,true 变为 1。

    所以两个操作数的类型都是int。第二个外部比较产生true,因为false->0 小于1,即d 的值。

    【讨论】:

      【解决方案2】:

      您的代码编译时没有错误,实际错误发生在链接时。链接器很可能无法找到 32 位版本 的运行时库。您是否已将它们安装到您的系统上?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-08
        • 2019-08-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2020-06-20
        相关资源
        最近更新 更多