2016-04-15 6 views
4

Ich habe Probleme, ein GCC-Problem zu umgehen. Ich erlebe es unter GCC 4.8, aber nicht 5.1. Es sieht so aus, als ob es here und/oder here gemeldet wurde.Fehler "angefragte Ausrichtung ist keine ganzzahlige Konstante"

Die Ausgabe Oberflächen wie folgt:

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; 
} 

Und:

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

Es ist auch Art wichtig, dass ich die static const halten, weil Clang sowie GCC nicht optimieren. Und C++ 03 ist eine Voraussetzung.

Hier ist eine verwandte Frage, aber es identifiziert nur den Fehler und bietet keine Umgehungslösung: Using constant from template base class.

Was kann ich tun, um das Problem zu umgehen?

Hier ist der Problem Compiler, aber es gibt wahrscheinlich andere da draußen eine der Probleme für 3 Jahre oder so blieb.

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

Die eigentliche Anwendungsfall ist ein wenig komplizierter. Wenn das Gerät SSE2 oder höher bietet, ist die Ausrichtung 16. Wenn das Gerät SSE4 oder höher anbietet, ist die Ausrichtung 32. Andernfalls greifen wir auf die natürliche Ausrichtung zurück. So seine Art näher an:

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

machen die Ausrichtung einen Template-Parameter führen würde eine Möglichkeit? – Yuushi

+0

@Yuushi - Ich habe den Testcode ausgeführt und es hat funktioniert, aber der Template-Parameter musste direkt im '__attribute__' verwendet werden. Ich denke, wir werden den Vorschlag von Serge verwenden, die Konstante im Wesentlichen zu spiegeln. – jww

Antwort

1

Nun, wie Sie sagen, dass C++ 03-Unterstützung eine Voraussetzung ist, würde ich einen Schritt zurück, um einen (ja C-ish ...) gute alte definieren:

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 
}; 

Natürlich ist die Definition nicht lokal für die Struktur und ist in allen folgenden Zeilen zugänglich. Aber schließlich tut es nicht viel weh (*) und erlaubt alten Compilern, das zu verstehen, ohne einen magischen litteral zu wiederholen (hier 16).

(*) Es könnte nur dann möglich, Fehler verbergen, wenn in der gleichen Datei später Sie in der Nähe von Deklarationen verwenden:

static const int CONST_ALIGNER = 12; 
... 
int b = CONST_ALIGN; // TYPO should have been CONST_ALIGNER 

Dies zu einem harten Fehler

finden
+0

Seine Art von hässlich, aber ich nehme es .... – jww

Verwandte Themen