B>Наткнулся на непонятное мне поведение компилятора (точнее, линкера, наверное) B>Есть три файла
... B>Почему проект собрался? B>Ведь объявление f() в head.h и определение f() в head.cpp неодинаковы!
Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям.
Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции.
Поэтому никаких проблем с точки зрения линкера нет.
А>А вот у Microsoft Visual C++ 2003 другая точка зрения. Он грязно ругается на стадии линковки. А>Может, это все-таки баг?
У MS возвращаемое значение влияет на генерацию уникального имени, что позволяет отлавливать такие ошибки.
Это также должно позволять перегружать функции только по возвращаемому значению.
Однако как показывает твой пример это не переносимо.
MS>Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям. MS>Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции. MS>Поэтому никаких проблем с точки зрения линкера нет.
Дык, я не собирался ее перегружать! Просто хочу использовать функцию из одного .cpp в другом, для чего вынес ее объявление в .h . Я только начинающий в с++, но кажется в данном случае делал все правильно. И я очень удивлен, что компилятор не предупредил меня, что я опечатался и типы возвращаемых значений объявлений функции в head.h и head.cpp не совпадают!
Ведь строчка
x=f();
в main.cpp — серьезная ошибка, учитывая, что f() — функция не возвращающая значения.
Имхо, компилятор не должнен пропускать подобных ляпов.
Здравствуйте, Bless, Вы писали:
MS>>Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям. MS>>Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции. MS>>Поэтому никаких проблем с точки зрения линкера нет.
B>Дык, я не собирался ее перегружать! Просто хочу использовать функцию из одного .cpp в другом, для чего вынес ее объявление в .h . Я только начинающий в с++, но кажется в данном случае делал все правильно. И я очень удивлен, что компилятор не предупредил меня, что я опечатался и типы возвращаемых значений объявлений функции в head.h и head.cpp не совпадают! B>Ведь строчка B>
B> x=f();
B>
B>в main.cpp — серьезная ошибка, учитывая, что f() — функция не возвращающая значения. B>Имхо, компилятор не должнен пропускать подобных ляпов.
MS>>Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям. MS>>Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции. MS>>Поэтому никаких проблем с точки зрения линкера нет.
B>Дык, я не собирался ее перегружать! Просто хочу использовать функцию из одного .cpp в другом, для чего вынес ее объявление в .h . Я только начинающий в с++, но кажется в данном случае делал все правильно. И я очень удивлен, что компилятор не предупредил меня, что я опечатался и типы возвращаемых значений объявлений функции в head.h и head.cpp не совпадают!
... B>Имхо, компилятор не должнен пропускать подобных ляпов.
С точки зрения компилятора все правильно.
Обычная практика, подходящая под большинство случаев:
Если в c/cpp файле пишете функцию, которая должна быть только внутри этого файла — делайте её static
Если эта функция используется в других единицах трансляции (в других c/cpp файлах), то желательно завести отдельный h(hpp) файл, в котором эта функция описана и включать этот файл как из файла реализации так и из файла в котором эта функция используется.
Применительно к вашему примеру:
head.cpp реализует функцию void f(), которым пользуется другой файл (main.cpp).
В файле head.h эта функция описана. Включаем этот заголовочный файл в ОБА файла.
Т.е. в вашем примере достаточно включить head.h в head.cpp и компилятор будет недоволен.
Re[4]: gcc и определение функций
От:
Аноним
Дата:
09.08.06 13:27
Оценка:
MS>Включаем этот заголовочный файл в ОБА файла.
Ок, спасибо, буду иметь в виду.
MS>С точки зрения компилятора все правильно.
А вот у Microsoft Visual C++ 2003 другая точка зрения. Он грязно ругается на стадии линковки.
Может, это все-таки баг?