2016-04-15 4 views
4

У меня возникли проблемы с работой по проблеме GCC. Я испытываю это под GCC 4.8, но не 5.1. Похоже, что его сообщили here и/или here.Ошибка «запрошенное выравнивание не является целочисленной константой»

На выпуск поверхности следующим образом:

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 также является обязательным требованием.

Вот и связанный с этим вопрос, но он просто идентифицирует ошибку и не предлагает обходное решение: Using constant from template base class.

Что я могу сделать, чтобы обойти проблему?


Вот компилятор проблемы, но, возможно, есть и другие, рассматривающие одну из проблем, оставшихся в течение 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; 
} 
+0

делает ориентирующей параметр шаблона Возможность? – Yuushi

+0

@Yuushi - я запустил тестовый код, и он сработал, но параметр шаблона должен был использоваться непосредственно в '__attribute__'. Я думаю, мы собираемся использовать предложение Сержа по существу отражать константу. – jww

ответ

1

Ну, как вы говорите, что поддержка 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 

Это привело бы к трудно найти ошибку

+0

Его вид уродливый, но я возьму его .... – jww