J’ai un fichier “test.cxx” avec
namespace net { extern "C" { #include } } int main() { htons(1024); }
Lors de la compilation avec -O1 ou plus, tout va bien.
Lors de la compilation avec -O0 :
error: 'htons' was not declared in this scope suggested alternative: 'net::htons'
Ensuite, je change htons en net :: htons .
Lors de la compilation avec -O0 tout va bien.
Lors de la compilation avec -O1 ou plus:
error: expected unqualified-id before '(' token
Reproduit cela sur gcc-4.9.2 et clang-3.7.0. Quelqu’un peut-il expliquer pourquoi cela se produit?
Cela se produit car à -O0
, l’appel est compilé dans la fonction htons
et votre déclaration pour cette fonction est à l’intérieur de l’ namespace net
. Dans la version optimisée, -O2
par exemple, l’appel est remplacé par une macro.
Vous pouvez le vérifier en pré-compilant votre programme en utilisant gcc -O0 -E
v / s gcc -O2 -E
Quand htons est utilisé
A -O2
, htons
est traduit en
int main() { (__extension__ ( { register unsigned short int __v, __x = (unsigned short int) (1024); if (__builtin_constant_p (__x)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; } )); }
Faire le code ne pas jeter l'erreur de résolution.
erreur: 'htons' n'a pas été déclaré dans cette scope
Quand net :: htons est utilisé
Lorsque vous remplacez ntohs
par net::ntohs
, ntohs
define est utilisé / exposé pour l'optimisation et votre code pré-traité ressemble à:
int main() { net::(__extension__ ({... /* removed for Brevity */ ...})); }
Et donc l'erreur
erreur: id non qualifié attendu avant '(' jeton
Pourquoi ça arrive
htons
peut être implémenté comme une fonction ou une macro. S'il est défini en tant que macro, htons
fonctionnerait bien. Mais si elle est définie comme une fonction net::htons
fonctionnerait bien.
Il apparaît à -O1
ou supérieur, les fichiers d'en-tête exposent les versions macro au lieu de la fonction.
Solutions possibles
using namespace net; // Not recommended
#ifndef htons // Recommended using net::htnos; #endif
extern "C" { // Add all declarations in global space #include }