2012-04-10 50 views
5

Stavo riscontrando alcuni problemi con un codice di esempio che stavo testando, poiché la funzione abs non restituiva il risultato corretto. abs (-2) è stato outputing -2 (questo, tra l'altro, si suppone sia la funzione valore assoluto, se era chiaro)conflitto nome funzione GCC

Dopo aver ottenuto un po 'disperata, alla fine ho avuto il seguente codice

#include <stdio.h> 

unsigned int abs(int x) { 
    return 1; 
} 

int main() { 
    printf("%d\n", abs(-2)); 
    return 0; 
} 

Questo non fa nulla di utile ma serve a mostrare il mio problema. Questo era in uscita -2, quando era previsto l'output 1.

se cambio il nome della funzione in qualcos'altro (ad esempio abs2), il risultato è ora corretto. Inoltre, se lo cambio per ricevere due argomenti invece di uno, risolve anche il problema.

La mia ipotesi ovvia: un conflitto con la funzione di standart abs. Ma questo non spiega ancora perché l'output è -2 (dovrebbe essere 2, se si utilizza la funzione standart abs). Ho provato a controllare l'uscita montaggio di entrambe le versioni (con la funzione denominata addominali e ABS2)

Ecco l'output diff per entrambi i montaggi:

23,25c23,25 
< .globl abs 
< .type abs, @function 
< abs: 
--- 
> .globl abs2 
> .type abs2, @function 
> abs2: 
54c54 
< .size abs, .-abs 
--- 
> .size abs2, .-abs2 
71c71,74 
< movl -4(%rbp), %edx 
--- 
> movl -4(%rbp), %eax 
> movl %eax, %edi 
> call abs2 
> movl %eax, %edx 

Da quanto ho capito, la prima versione (dove la funzione è chiamato abs) sta semplicemente scartando la chiamata di funzione, quindi utilizzando il parametro x invece di abs (x)

Quindi per riassumere: perché questo accade, soprattutto perché non sono riuscito a trovare un modo per ottenere alcun tipo di avviso o errore a riguardo.

Testato su Debian Squeeze, GGC 4.4.5, ed anche su gcc 4.1.2

+0

ecco un esempio in ideone http://ideone.com/YpnkE –

risposta

7

GCC sta giocando trucchi su di voi a causa della interazione dei seguenti elementi:

  • abs è un incorporato in funzione;
  • si sta dichiarando abs per restituire unsigned int mentre lo standard (e incorporato) abs restituisce signed int.

Provare a compilare con gcc -fno-builtin; sulla mia scatola, che dà il risultato previsto di 1. Compilare senza questa opzione ma con abs dichiarato come restituito signed int causa la stampa del programma 2.

(La vera soluzione a questo problema è di non utilizzare identificatori di libreria per le proprie funzioni. Si noti inoltre che non si dovrebbe essere la stampa di un unsigned int con %d.)

+0

Grazie, che ne chiarisce una parte. sapevo delle funzioni built-in, e anche se qualcosa come -fno-builtin avrebbe potuto risolverlo, ma non conoscevo il nome effettivo del flag. Tuttavia, quando si utilizza la seconda soluzione (dichiarando la funzione come firmata int), l'output di 2 implica che la funzione incorporata viene chiamata al posto della mia, il che porta alla mia altra domanda: non dovrei ricevere un avviso su questo comportamento? In un progetto reale su larga scala, questo tipo di problema avrebbe potuto essere un vero grattacapo per identificare – Naps62

+0

@ Naps62: sì, un avvertimento sarebbe stato carino, ma sembra GCC (anche '-Wall -Wextra -pedantic') solo non te ne darò uno Meglio stare attento con i tuoi identificatori. –

2

gcc ottimizza la chiamata a abs() di utilizzare il suo built-in abs(). Quindi se usi l'opzione -fno-builtin (o definisci il tuo abs() come restituito int), noterai che ottieni il risultato corretto. Secondo this (citando):

GCC include incorporato nelle versioni di molte delle funzioni della libreria standard C .Le versioni con prefisso _ incorporato nello saranno sempre considerate come aventi lo stesso significato della funzione di libreria C anche se si specifica l'opzione -fno-builtin. (vedi C Dialect Options) Molte funzioni di queste funzioni sono ottimizzate solo in alcuni casi; se sono non ottimizzati in un caso particolare, verrà emessa una chiamata alla funzione libreria .

Had You incluso stdlib.h, che dichiara abs(), in primo luogo, si otterrebbe un errore in fase di compilazione.

+0

Il programma che ho postato non rientra nella funzione integrata come ci si aspetterebbe. invece è semplicemente ignorando la chiamata di funzione, trattando abs (-2) come -2. Inoltre, ho provato il tuo suggerimento di includere stdlib.h, e non ho ottenuto alcun errore in fase di compilazione, il problema è rimasto – Naps62

+0

Trovo difficile da credere, dato che stai definendo una funzione chiamata 'abs()' con tipi in conflitto con quello in 'stdlib.h'. Anche senza opzioni rigide o pedanti, gcc 4.1.2 e 4.4.7 emettono entrambi errori di compilazione. –

2

Suona molto come this bug, che risale al 2007 e viene rilevato come fisso.

Si dovrebbe ovviamente provare a compilare senza intrusioni di GCC, ovvero passare -fno-builtin (o solo -fno-builtin-abs per eseguire lo snipe solo abs()) durante la compilazione.

Problemi correlati