2016-10-04 1 views
1

Donc, ma question est la suivante. Si dans un fichier d'en-tête, j'ai une déclaration de fonction:Spécifier des pointeurs comme restreindre seulement dans la déclaration?

extern void func(void* restrict, void* restrict); 

puis dans un fichier source, je le définir comme tel:

void func(void*, void*) {} 

est-ce un problème? Les qualificatifs restrict sont-ils perdus?

P.S. Cela permet de compiler le fichier source en mode C89 et de remplacer le prototype de l'en-tête par la version C89/C99 correspondante avec une macro conditionnelle.

+1

Si vous avez une macro conditionnelle, pourquoi essayez-vous même de faire une définition couvrant les deux cas? La façon «correcte» de traiter de tels scénarios est soit de fournir deux déclarations, de les séparer par le garde de macro, soit de masquer le mot-clé problématique sous un identifiant de macro, lui-même donné différentes définitions par le garde. – Leushenko

Répondre

2

«C'est que je peux compiler le fichier source en mode C89 » - simple raison: restrict est pas un mot-clé réservé jusqu'à C99 see forword of C11 (C99 est la 2ème édition), il sera simplement utilisé comme un nom, ce qui est ignoré dans le prototype.

Mais les deux déclarateurs de fonctions (prototype et définition) doivent spécifier le même type, c'est-à-dire que restrict est requis dans les deux.

Vous devez compiler l'en-tête et l'implémentation avec la version C correcte. Pour restrict, la définition est généralement plus pertinente que le prototype, mais le compilateur peut être en mesure de détecter les violations dans l'appelant. Supposons toujours que vous vous fiez à de tels hacks pour casser votre code.


Après les commentaires, en essayant un peu de voyance:

Si vous voulez faire le code de compilation avec l'ancien C90, encore tirer parti des nouvelles fonctionnalités lorsque cela est utile, vous pouvez utiliser une macro:

#if this_is_c99_or_c11 
#define RESTRICT retrict 
#else 
#define RESTRICT 
#endif 

void f(int * RESTRICT p); 

... 

void f(int * RESTRICT p) 
{ 
    ... 
} 

Rappelez-vous qu'il peut y avoir des problèmes de compilation de l'appelant et de l'appelé. Vérifiez l'ABI de votre cible.

+0

Il sera utilisé comme un nom, qui est ignoré, mais il échouera également à compiler en raison de 'redéfinition du paramètre' – DeiDei

+0

Où voulez-vous dire qu'il va échouer? Veuillez lire la dernière phrase de mon premier paragraphe. «void *» n'est pas autorisé dans le déclarateur de la définition. – Olaf

+0

Déclarer une fonction comme 'void f (void * restreindre, void * restrict);' échoue à compiler dans mon 'clang-3.9' en mode C89 et je cite' error: redéfinition du paramètre 'restrict''. Sinon, votre réponse m'a dit ce que je faisais déjà en pratique, donc je vais marquer comme correct. – DeiDei