Keil C51: возможная ошибка функций с одинаковым именем, но разными параметрами?

Это не совсем вопрос, так как он уже решен. Но я хотел бы поделиться этим здесь, так как кто-то может столкнуться с той же проблемой. И я хотел бы получить более глубокое объяснение по этому поводу.

Я использую Keil µvision3 для программирования на C8051F340(который, я думаю, не имеет отношения к этому вопросу). В моем main.c у меня есть что-то вроде:

... // accessible code
getInput();
... // not accessible after modification

и в mobile.c(игнорировать заголовки, включает в себя, blablabla, которые не имеют значения):

void getInput()
{
    ...
}

И это было хорошо. Однако после того, как я сделал некоторые изменения в коде,

void getInput(struct SomeStruct *ss)
{
    ...
}

компиляция и загрузка на чип завершена без ошибок. Хотя я нашел предупреждение:

*** ПРЕДУПРЕЖДЕНИЕ L2: ССЫЛКА, СДЕЛАННАЯ ДЛЯ Неразрешенного ВНЕШНЕГО

СИМВОЛ: ПОЛУЧЕНИЕ

Но я был немного ленив, и у моих коллег было много других предупреждений, которые делали невозможным чтение.(Дурная привычка!)

Что-то, что я хотел бы изучить:

  1. Почему Keil разрешает такую ​​вещь компилировать без ошибок (в C это определенно должна быть функция, не объявляющая ошибку)?
  2. Что говорит ССЫЛКА НА РАЗРЕШЕННОЕ ВНЕШНЕЕ? Он нашел функцию с тем же именем, но не смог ее разрешить из-за разных параметров или просто разрешил любую функцию, не проверяя ее существование в проекте? Я не мог найти, как сгенерировать ассемблерный код, поэтому я не совсем уверен.

1 ответ

В C, если вы используете функцию, которая не объявлена ​​в заголовочном файле, компилятор угадывает определение (и зависит от флагов компилятора) и выдает предупреждение. Когда компилятор генерирует код ассемблера, он больше не знает об аргументах, только о символах / символьных указателях, следовательно, компоновщик не может обнаружить это (C++ может, поскольку имена символов там включают информацию о параметрах из-за поддержки перегрузки параметров). pseduecode:

push arg1
call getInput   //the linker only sees this, does not know about stack-frame / arguments

Когда дело доходит до предупреждения GETINPUT, кажется, что вы не включаете скомпилированный файл C, содержащий фактический символ, в конечный результат (компоновщик Keil, кажется, помещает символы в верхний регистр, даже если имя должно было быть getInput, или, возможно, вы пытались называть GETINPUT так же?)

Другие вопросы по тегам