PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C - compile time assertion


noid
2017-05-29, 15:26:53
Moin,

eigentlich ein "leichtes" Problem. Ich würde gerne verhindern, dass ein "nicht-konformes" Definieren von Daten zum compieren führt.


//ok:
const D_list_T A_DList[] =
{
D_A,
D_B,
INVALID_D_NUMBER
};
//nok:
const D_list_T B_DList[] =
{
D_C,
D_D
};


Jetzt sollte die Datei eigentlich autogeneriert werden, aber es gibt Sonderfälle. Dummerweise kann ich bei dem compiler erkennen, dass er weiß(!) ob

(A_DList[(sizeof(A_DList) / sizeof(D_list_T)) - 1] == INVALID_D_NUMBER)
(B_DList[(sizeof(B_DList) / sizeof(D_list_T)) - 1] == INVALID_D_NUMBER)

true oder false würde als expression. Ich bekomme aber keine static assertion definiert weil der Ausdruck nicht constant ist.

Ein häßliches Perl-script hätte ich, eine run-time assertion wäre machbar (wobei ich denke die meisten bemerken es nicht wirklich). Geniale Ideen?

Gnafoo
2017-05-29, 22:45:04
Ich bin mir nicht ganz sicher (mit den "neuen" C++11-Funktionen habe ich nicht viel Erfahrung), aber probiere einmal das Array mit constexpr anstelle von const zu definieren.

Siehe:
https://stackoverflow.com/questions/10965241/compile-time-array-constants

Marscel
2017-05-29, 23:03:54
Wenn noid die Build-Chain auf C++11 oder neuer umstellen darf. ;)

noid
2017-05-29, 23:04:52
Müsste ich mal mit dem makefile rumfummeln, ob ich den code wrappen kann dass c++ drüberläuft. Durch den c-compiler sicherlich nicht.

Was mich halt wirklich fuchst: der compiler sagt eigentlich zu recht ich darf das nicht, aber die optimization im compiler nutzt das wissen.

Gnafoo
2017-05-29, 23:38:28
Ah ich habe ganz übersehen, dass es um "klassisches" C geht. Das schränkt die Möglichkeiten natürlich ein. Das einzige was mir da noch einfällt sind Tricks mit dem Präcompiler. Nach dem Motto:


BEGIN_ARRAY(A_DList)
ENTRY(D_A)
ENTRY(D_B)
ENTRY(INVALID_D_NUMBER)
END_ARRAY


Und dann ein paar include-Dateien, so dass der Code mit Include-Datei #1 das Array definiert und mit Include-Datei #2 einen Syntax-Fehler produziert, wenn das Array nicht richtig definiert wurde.

Hübsch ist natürlich was anderes :freak:.

Oid
2017-05-30, 08:04:01
Müsste ich mal mit dem makefile rumfummeln, ob ich den code wrappen kann dass c++ drüberläuft. Durch den c-compiler sicherlich nicht.

Was mich halt wirklich fuchst: der compiler sagt eigentlich zu recht ich darf das nicht, aber die optimization im compiler nutzt das wissen.

Naja, eine static assertion wird halt nach dem Präprozessor und vor dem eigentlichen kompilieren abgearbeitet.

Die ganzen Optimierungen laufen alle erst danach.

Für mich sieht das nach dem klassischen Anwendungsfall für eine runtime-assertion aus.

noid
2017-05-30, 20:30:50
Ah ich habe ganz übersehen, dass es um "klassisches" C geht. Das schränkt die Möglichkeiten natürlich ein. Das einzige was mir da noch einfällt sind Tricks mit dem Präcompiler. Nach dem Motto:


BEGIN_ARRAY(A_DList)
ENTRY(D_A)
ENTRY(D_B)
ENTRY(INVALID_D_NUMBER)
END_ARRAY


Und dann ein paar include-Dateien, so dass der Code mit Include-Datei #1 das Array definiert und mit Include-Datei #2 einen Syntax-Fehler produziert, wenn das Array nicht richtig definiert wurde.

Hübsch ist natürlich was anderes :freak:.

Du meinst die Leute bekommen das hin, wenn sie das andere schon nicht hinbekommen? :biggrin:

Naja, eine static assertion wird halt nach dem Präprozessor und vor dem eigentlichen kompilieren abgearbeitet.

Die ganzen Optimierungen laufen alle erst danach.

Für mich sieht das nach dem klassischen Anwendungsfall für eine runtime-assertion aus.

runtime assertion it is :freak: