web-dev-qa-db-fra.com

C avertissement Sentinelle manquante dans l'appel de fonction

Ceci est mon avertissement.

Missing sentinel in function call

Comment je peux l'enlever.

j'utilise le compilateur linux & gcc.

41
ambika

Il semble que vous n'ayez pas terminé une déclaration de tableau avec NULL. Sans la valeur null, vous pouvez avoir une certaine étrangeté de la mémoire car le runtime ne saura pas où se termine le tableau et le bit de mémoire suivant commence.

63
Michael Gaylord

Je viens de tomber sur le même problème. Le code qui le provoquait pour moi était ...

execl("/bin/bash", "/bin/bash", fname, '\0');

mais ça devrait être ...

execl("/bin/bash", "/bin/bash", fname, (char *)0);

Le problème avec la première version est que la liste des paramètres est censée se terminer par un pointeur nul. Mais '\ 0' n'est pas un pointeur nul, c'est un caractère nul. Donc, la valeur (0) est correcte, c'est juste que le type est incorrect.

Le (char *) 0 est également zéro, mais converti en char pointeur, qui est un pointeur nul (c'est-à-dire qu'il pointe vers l'adresse 0). Ceci est nécessaire pour que le système puisse dire où se termine la liste des paramètres afin de ne pas continuer à rechercher des paramètres après le dernier. Faire cela entraînerait des pointeurs invalides qui pourraient pointer vers n'importe quelle mémoire - ce qui provoquerait probablement une erreur de segmentation.

Ce (char *) 0 s'appelle la sentinelle, et c'est ce qui manquait dans le premier exemple.

Notez enfin que NULL est défini comme (void *) 0, donc

execl("/bin/bash", "/bin/bash", fname, NULL);

Fonctionne tout aussi bien et est un peu plus pratique. (Merci à @mah pour cela).

46
Peter Bagnall

Dans Xcode si vous codez en objectif-c et que vous utilisez des méthodes qui prennent une liste de paramètres variables, vous devez ajouter nil objet à la fin de la liste.

Par exemple:

N SArray * names = [NSArray arrayWithObjects: @ "Name1", @ "Name2"]; // entraînera l'avertissement mentionné ci-dessus

Cependant, NSArray * names = [NSArray arrayWithObjects: @ "Name1", @ "Name2", nil]; // Correct

J'espère que cela vous aidera!

18
kslcam

Un exemple trivial:

#include <stdio.h>
#include <stdarg.h>

void print_strings(const char* first, ...) __attribute__((sentinel));

void print_strings(const char* first, ...)
{
    va_list ap;
    const char* tmp;
    if (!first)
        return ;
    printf("%s\n", first);
    va_start(ap, first);
    while (1) {
        tmp = va_arg(ap, const char*);
        if (tmp == 0)
            break;
        printf("%s\n", tmp);
    };
    va_end(ap);
}

int main()
{
    print_strings("how are you?", "i'm fine", "and you?", NULL);
    return 0;
}

En général, si vous appelez print_strings en tant que print_strings("how are you?", "I'm fine", "and you?") qui n'a pas de fin NULL, GCC se plaindra "sentinelle manquante".

Parce que nous ajoutons l'attribut de fonction sentinelle à la fonction print_strings. C'est une extension gcc pour spécifier que les arguments variables doivent se terminer par NULL. Donc, si vous ne mettez pas fin aux arguments variables avec NULL, le compilateur pourrait le détecter et afficher l'avertissement.

2
Jichao

Sentinel signifie garder ou protéger .. Donc, dans ce contexte, l'erreur se produit car vous risquez de manquer les paramètres de garde. Dans le cas où vous utilisez un tableau ou un dictionnaire, assurez-vous qu'après la dénomination des objets, vous les terminez avec le mot clé nil.

Exemple:

[NSDictionary dictionaryWithObjectsAndKeys:@"UIAlertView", kSectionTitleKey,
              @"Show Custom", kLabelKey,
              @"AlertsViewController.m - alertOtherAction", kSourceKey];

L'instruction ci-dessus produira une erreur "Sentinelle manquante dans l'appel de fonction"

Syntaxe correcte:

[NSDictionary dictionaryWithObjectsAndKeys:@"UIAlertView", kSectionTitleKey,
              @"Show Custom", kLabelKey,
              @"AlertsViewController.m - alertOtherAction",kSourceKey,nil];
1
taus-iDeveloper

Vous pouvez passer NULL comme: execl ("/ bin/bash", "ls", "- l", NULL); Le dernier paramètre doit toujours être 0. Il s'agit d'un terminateur NULL. Puisque la liste d'arguments est variable, nous devons avoir un moyen de dire à C quand elle doit se terminer.

1
Sanidhya Srivastava