2014-06-28 8 views
5

Lo standard dice:principale function() con la firma di sbagliato viene chiamato

5.1.2.2.1 all'avvio del programma

La funzione chiamata all'avvio del programma prende il nome principale. L'implementazione non dichiara alcun prototipo per questa funzione. Deve essere definito con un tipo restituito di int e senza parametri: int principale (vuoto) {/ * ... * /} o con due parametri (indicato qui come argc e argv, sebbene qualsiasi nome possa essere utilizzato, poiché sono locali alla funzione in cui sono dichiarati): int main (int argc, char argv []) {/ ... * /} o equivalente; 10) o in qualche altro modo definito dall'implementazione .

Se scrivo questo:

#include <stdio.h> 

struct some_struct 
{ 
    int i; 
}; 

float main(struct some_struct s) 
{ 
    printf("Why does this main get called?\n"); 
} 

In realtà, viene chiamato con qualsiasi prototipo, come la vedo, e non v'è alcun errore qualsiasi runtime.

Perché non è proibito? Non ci sono ragioni per questo? Inoltre, come viene chiamato se la firma è sbagliata?

Ho usato gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

+5

Compila con '-Wall -Werror'o' -pedantic-errors' e vedrai che non è permesso. – ouah

+0

Fondamentalmente, se main() non è digitato, il valore predefinito è int, se è stato digitato e non a un int - è un errore. –

+0

Capito dei flag di compilazione, ma come viene chiamato allora? Cerca solo la funzione con il nome "main" e ignora qualsiasi argomento? – acrilige

risposta

2

A partire con la conformità di serie:

1 nella presente norma internazionale, ‘‘deve’’ deve essere interpretato come un requisito su un implementazione o su un programma; al contrario, '' non deve '' deve essere interpretato come una proibizione .

2 Se un ‘esigenza ‘deve’’ o ‘‘non sono’’ che appare al di fuori di un vincolo o di vincolo di runtime viene violato, il comportamento è indefinito . [...]

ora vedere l'accento sulla norma che hai citato:

[...]. È deve essere essere definito con un tipo di ritorno di int e con [...]

Nel caso,

float main(struct some_struct s){...} 

"shall" requisito è fuori di costrizione perché norma chiaramente che main tipo di ritorno è int sia senza parametri

int main(void) { /* ... */ } 

oa due parametri

int main(int argc, char argv[]) {/... */ }  

Ciò significa che il comportamento del programma è non definito.

+0

quindi, 'main() {...}' è un comportamento non definito? L'ho visto molto – acrilige

+1

Consentito in C89. C99 e quest'ultimo hanno deprecato questa firma. – haccks

2

tua citazione da La norma stabilisce che "qualche altro modo implementazione definita". Sembra che gcc sia abbastanza liberale in ciò che consente come firma per main; sembra ignorare il parametro che stai passando. Se si compila con gcc -Wall, si ricevono avvertimenti sul prototipo di main che non è quello che si aspetta.

clang è meno permissivo del prototipo principale. Accetterà il tipo di reso di float con un avviso, ma eseguirà un errore sull'argomento struct.

C cerca le funzioni solo per nome, quindi il linker non si preoccupa del tipo di ritorno e dei parametri insoliti.

+0

Questo è strano per Clang. Si sente nel modo sbagliato. Dovrebbe essere un errore corretto non restituire il tipo 'int' (poiché non esiste un programma ben strutturato che * anche * abbia un' float main (...) ', poiché' main' non deve essere sovraccaricato). Tuttavia, le implementazioni sono libere di supportare qualsiasi tipo di parametro per 'main', quindi sarebbe corretto dire" la tua firma è ignorata "o così e ancora essere conforme. –

Problemi correlati