2013-04-10 3 views
5

J'ai un code assembleur PowerPC traduit par un compilateur croisé gcc avec cette fonction:Comment faire pour supprimer « avertissement: le contrôle atteint la fin de la fonction non vide »

uint32_t fill_cache(void) 
{ 
    __asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */ 
    /* More asm here modifying R3 and filling the cache lines. */ 
} 

qui, sous le PowerPC EABI, retourne le valeur calculée en R3. Lors de la compilation, je reçois

foo.c:105: warning: control reaches end of non-void function 

Y at-il un moyen d'apprendre à gcc qu'une valeur est réellement retournée? Ou y a-t-il un moyen de supprimer l'avertissement (sans supprimer -Wall ou en ajoutant -Wno- *)? Je souhaite supprimer très sélectivement cet avertissement uniquement pour cette fonction afin de laisser le niveau d'alerte générale aussi élevé que possible.

L'annulation de cette fonction n'est pas une option car la valeur calculée est requise par l'appelant.

Répondre

12

Solution 1: avec diagnostic pragmas vous pouvez supprimer localement certains contrôles de diagnostic. L'option spécifique (qui est également implicite par -Wall) qui se plaint de l'absence de retour dans une fonction non-nulle est -Wreturn-type. Ainsi, le code spécifique pour supprimer l'avertissement est:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wreturn-type" 
/* Your code here */ 
#pragma GCC diagnostic pop 

Vous pouvez savoir quelle option est à l'origine de l'avertissement en compilant avec -fdiagnostics-show-options. Il ajoutera simplement l'option au message d'avertissement.

La solution 2: définit un register variable et le place dans le registre souhaité. Reportez-vous à la variable dans un inline assembler template, avec le code résultant:

uint32_t fill_cache(void) 
{ 
    register uint32_t cacheVal __asm__ ("r3"); 

    __asm__ __volatile__ ("addi %0, 0, 0" : "=r" (cacheVal)); 
    /* More code here */ 

    return cacheVal; 
} 

Le modificateur volatil est de faire en sorte que l'instruction ne soit pas retirée ou d'une autre manière affectée par la stratégie non souhaitable d'optimisation.

Solution 2 est préféré pour au moins deux raisons:

  1. La valeur d'un pas de fonction non vide de retour est non défini dans la mesure où la norme est concerné.
  2. Il n'y a aucun risque de supprimer les (nouveaux) avertissements de diagnostic que l'on n'avait pas l'intention de supprimer en premier lieu.
1

Fonction pourrait être déclarée comme naked, dans ce cas compilateur ne produirait pas Prolog & et epilog supposerait que programmeur conserve tous les registres nécessaires et met la valeur de sortie dans le registre correct (s) avant le retour.

uint32_t fill_cache(void) __attribute__((naked)); // Declaration 
// attribute should be specified in declaration not in implementation 

uint32_t fill_cache(void) 
{ 
    __asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */ 
    /* More asm here modifying R3 and filling the cache lines. */ 
} 

Un peu en retard, mais peut-être quelqu'un interviendrons cela aussi :)

PS: Pour ma connaissance __asm__ ainsi que la syntaxe __volatile__ sont std=c89. Pratiquement il n'y a pas de différence entre __asm__ & asm dans GNU GCC. Mais l'approche moderne est un style sans fondement: asm volatile.

asm_language

Questions connexes