错误信息:“请求的对齐方式不是整数常量”

4
我在解决一个GCC问题时遇到了困难。我在GCC 4.8下遇到这个问题,但5.1下没有。看起来这个问题已经被报告在这里和/或这里
这个问题表现如下:
template <bool B>
struct S
{
    static const int ALIGN = 16;
    __attribute__((aligned(ALIGN))) int x;
};

int main(int argc, char* argv[])
{
    S<true> s1;
    S<false> s2;
    return 0;
}

同时:

$ g++ test.cxx -o test.exe
test.cxx:9:41: error: requested alignment is not an integer constant
     __attribute__((aligned(ALIGN))) int x;

保留static const很重要,因为Clang的优化不如GCC。而且,C++03也是必需的。

这里有一个相关的问题,但它只是确定了错误,并没有提供解决方法:使用模板基类中的常量

我该怎么解决这个问题呢?


这是编译器的问题,但可能还有其他问题,因为其中一个问题已经存在了3年左右。

$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.

实际应用情况会更加复杂一些。如果计算机支持SSE2或以上,那么对齐方式为16。如果计算机支持SSE4或以上,则对齐方式为32。否则,我们将回退到自然对齐方式。因此,它更接近于:

template <class W, bool B, unsigned int S>
struct X
{
    static const int ALIGN = (B ? 16 : sizeof(W));
    __attribute__((aligned(ALIGN))) W x[S];
};

int main(int argc, char* argv[])
{
    X<int, true, 10> x1;
    X<long, false, 20> x2;
    return 0;
}

将对齐方式作为模板参数是可能的吗? - Yuushi
@Yuushi - 我运行了测试代码,它可以工作,但是模板参数必须直接在__attribute__中使用。我认为我们将采用Serge的建议,基本上反映常量。 - jww
1个回答

2

既然你说需要支持C++03,我会退回到一个(是的,类似于C语言的)好老的定义:

template <bool B>
struct S
{
    #define CONST_ALIGN 16
    static const int ALIGN = CONST_ALIGN;  // to allow using it later as S<B>.ALIGN
    __attribute__((aligned(CONST_ALIGN))) int x; // this uses a litteral int constant
};

当然,这个定义不仅限于结构体本身,而且在所有后续行中都可以访问。但毕竟这并没有太大的影响,(*)并且可以让旧的编译器理解它,而无需重复一个神奇的文字(这里是16)。
(*)如果您稍后在同一文件中使用近似声明,则只能隐藏可能的拼写错误。
static const int CONST_ALIGNER = 12;
...
int b = CONST_ALIGN;  // TYPO should have been CONST_ALIGNER

这将导致一个难以寻找的错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接