2010-10-01 5 views
4
int main() 
{ 
    int x=5,y=10,z=15; 
    printf("%d %d %d"); 
    return 0; 
} 

Sortie: 15 10 5 // Dans Turbo C 4,5Quelle est la sortie du code suivant?

3 Garbage values in gcc compiler 

Mon professeur m'a dit quand nous définissons les variables comme int x = 5, y = 10, z = 15; ils sont par défaut pris en tant que type automatique et stockés dans la pile.Lorsque vous essayez d'imprimer 3 valeurs entières sans utiliser leurs noms par printf(), il imprimera ces 3 valeurs au format LIFO comme le fait le compilateur Turbo C. Mais ce que je pense quand nous définissons 3 variables entières, ils ne peuvent pas être stockés dans des emplacements de mémoire continue.Alors que j'essaie d'imprimer 3 valeurs entières sans utiliser leurs noms, le compilateur imprimera trois valeurs du haut de la pile. la sortie viendra 3 valeurs de garbage comme dans gcc ..

+0

Alors, votre question est ...? –

+2

Obtenez un nouvel enseignant. S'il dit autre chose que «c'est un comportement indéfini, ne le fais pas», il ne sait pas de quoi il parle. – JeremyP

+0

@Daniel Standage qu'est-ce qui est logiquement correct? – Parikshita

Répondre

10

Ce code montre juste que Turbo C est faible à l'optimisation du code et met tout sur la pile, tandis que gcc est plus agressif et le maintient dans les registres ou le jette tous ensemble parce que ces trois variables ont pas de but .

Quoi qu'il en soit, appeler printf avec un motif qui nécessite trois arguments sans fournir ces arguments, est une erreur.

Mise à jour:

Comme explication: Je suppose que printf() aura toujours son argument de la pile, car il est une fonction avec une liste d'arguments variable. Ou quelqu'un connaît-il une autre convention d'appel pour des fonctions comme printf()? De plus, je suppose qu'il n'y a pas besoin de mettre autre chose sur la pile car il n'y a pas d'autres variables. Donc, cet appel erroné de printf affichera tout ce qui est au-dessus de la pile dans main(). Mais il pourrait y avoir d'autres architectures et conventions d'appel où mes assomptions ne tiennent pas.

+3

Étant donné que printf est une fonction de bibliothèque, je ne vois pas comment le compilateur est capable de choisir la manière de lui transmettre des paramètres. Une convention d'appel a été choisie lorsque la bibliothèque a été compilée et que le compilateur doit être conforme. – torak

+0

L'optimisation n'est pas dans l'appel de _printf() _ mais plutôt dans la façon dont les variables locales de _main() _ sont stockées. L'appel problématique de _printf() _ ne fait que révéler ce qu'il y a sur la pile. – Codo

4

Ceci est un comportement indéfini. Avec un compilateur d'optimisation, ces 3 valeurs peuvent être optimisées car elles ne sont pas utilisées. Il va imprimer des ordures.

0

En MingW-GCC: 3 valeurs de vidage.

Dans VC++ 2010: 0, 0 et une valeur de vidage.

2

S'il n'y a pas suffisamment d'arguments pour le format, le comportement n'est pas défini.

3

Le comportement est indéfini, ce qui signifie que le compilateur est libre de gérer la situation comme bon lui semble. En ce qui concerne la norme linguistique, Turbo C et gcc font tous les deux la bonne chose.

+3

Et le programmeur qui a écrit le code ne fait pas la bonne chose! –

1

Votre professeur a tort, mais pas entièrement.

Les variables déclarées dans une fonction sont par défaut auto plutôt que static.

int foo(void) { 
    static int x; 
    int y; 
    auto int z; 

    /* ...other code... */ 
} 

Cela signifie que dans la fonction ci-dessus y est automatique, comme z, même si le mot-clé auto n'est pas utilisé dans sa déclaration. Le mot clé auto n'est presque jamais utilisé, d'ailleurs.Beaucoup de programmeurs de langage C (et C) ne savent même pas que auto est un mot-clé parce qu'il est utilisé si rarement.

Etre une variable auto signifie généralement que la variable est stockée dans la pile système du programme ou dans des registres ou une combinaison de ceux-ci. Il peut être à des endroits différents à des moments différents au cours de l'exécution de la fonction, et les variables locales qui sont dans les registres sont souvent poussées vers la pile lorsqu'une autre fonction est appelée. Certaines variables locales peuvent même être optimisées, ce qui signifie qu'à un moment donné le compilateur a pu déterminer que la valeur future d'une variable particulière n'était plus nécessaire pour satisfaire les besoins d'entrée du futur code (ou la variable ne change pas et sa valeur est juste codé dans les instructions). Cela complique l'utilisation de débogueurs sur le code optimisé. Lorsque vous prenez l'adresse d'une variable locale, le compilateur tente de la verrouiller à une adresse spécifique (probablement en la stockant sur la pile). Lorsque la plupart des compilateurs regardent votre code, ils voient que les noms de ces variables locales ne sont pas utilisés après leur déclaration et peuvent décider de ne pas stocker leurs valeurs n'importe où. Même s'il stocke ces valeurs sur la pile, il peut également pousser d'autres valeurs sur la pile avant de configurer pour appeler printf. Tout comme le compilateur n'a pas à conserver les variables que vous avez nommées, il est également libre de créer ses propres variables temporaires.

Questions connexes