2014-10-30 3 views
-9

Я ожидаю ошибку в следующем коде, но после запуска вывода 5 может кто-нибудь сказать почему.Почему я получаю вывод «5»?

#include <stdio.h> 
void main() 
{ 
    int k = m(); 
    printf("%d", k); 
} 
void m() 
{ 
    printf("hello"); 
} 

потому что тип возврата недействителен, но когда мы объявляем его выше основного, то он дает ошибку.

+3

Это просто неопределенное поведение, которое все, что нужно сказать. –

+0

Имейте в виду, что вы кодируете C. – HuStmpHrrr

+1

К OP, будьте осторожны, задавая здесь вопросы C. Вы должны сделать домашнее задание раньше, иначе вы спуститесь - проголосовали в забвении. –

ответ

6

Данная программа является недействительной (далее объясняется, почему это следует ниже).

В C89, когда вы вызываете m(), или в C99, когда вы запускаете программу вообще, вызывается неопределенное поведение. Это означает, что все может случиться. Другими словами, компилятор должен справляться с правильными программами; и если вы допустили ошибку, вы можете получить нежелательные результаты (это не ограничивается недействительным результатом).

В C89 этот код на самом деле не требует никакой диагностики компилятора . Это просто вызывает неопределенное поведение. (Полезные компиляторы могут дать вам предупреждение в любом случае.)

Это происходит потому, что линия int k = m(); вызывает неявное объявление функции m() возвращение int и принимать неуказанные аргументы. Однако фактический корпус функции m возвращает void. Это означает, что если m когда-либо вызывается, то запускается неопределенное поведение.

В практическом плане, что вы можете испытывать в том, что функция main выглядит в том или ином регистре для значения, возвращенного из m, но функции тело m не установлен, что реестр, и это случилось, чтобы содержать 5 случайно , Не полагайтесь на это поведение.

Поскольку вы не использовали функции прототипов, компилятор не обязан диагностировать эту ошибку. Если вы использовали прототип функции (например, void m(void)), или если вы перемещаете void m() до main(), тогда компилятор должен предоставить диагностику. (Если вы все равно продолжаете запускать свою программу, игнорируя это сообщение, тогда все поведение программы не определено).

В C99 неявное объявление функций было удалено, а строка int k = m(); должна дать диагностику.


требует диагностики означает, что код имеет ошибку в соответствии со стандартом C, и компилятор должен сообщить вам сообщение. Компилятор может выбрать категоризацию этого сообщения как «предупреждение» и выпустить исполняемый файл в любом случае, однако код по-прежнему не соответствует этому сценарию и должен быть исправлен.

+0

Основной проблемой является не порядок декларирования. – Nit

+1

@ Нит хорошо - есть две основные проблемы, я исправлю свой пост –

+1

, но он дает результат 5, поэтому я удивляюсь .it должен дать ошибку – Aman