gcc и определение функций
От: Bless  
Дата: 08.08.06 13:29
Оценка:
Использую под windows IDE Code::Blocks v1.0, с которой идет minGW с gcc 3.4.4.

Наткнулся на непонятное мне поведение компилятора (точнее, линкера, наверное)
Есть три файла


main.cpp

#include <iostream>
#include "head.h"
using namespace std;
int main()
{
  double x;
  x=f();
    cout << x<< endl;
    return 0;
}


head.h
double f();


head.cpp

#include <iostream>
using namespace std;
void f(){
  cout<<"double f()"<<endl;

}



Почему проект собрался?
Ведь объявление f() в head.h и определение f() в head.cpp неодинаковы!
Re: gcc и определение функций
От: MShura  
Дата: 08.08.06 16:15
Оценка: 3 (1)
B>Наткнулся на непонятное мне поведение компилятора (точнее, линкера, наверное)
B>Есть три файла
...
B>Почему проект собрался?
B>Ведь объявление f() в head.h и определение f() в head.cpp неодинаковы!

Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям.
Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции.
Поэтому никаких проблем с точки зрения линкера нет.
Re[2]: gcc и определение функций
От: Bless  
Дата: 09.08.06 05:07
Оценка:
MS>Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям.
MS>Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции.
MS>Поэтому никаких проблем с точки зрения линкера нет.

Дык, я не собирался ее перегружать! Просто хочу использовать функцию из одного .cpp в другом, для чего вынес ее объявление в .h . Я только начинающий в с++, но кажется в данном случае делал все правильно. И я очень удивлен, что компилятор не предупредил меня, что я опечатался и типы возвращаемых значений объявлений функции в head.h и head.cpp не совпадают!
Ведь строчка
 x=f();

в main.cpp — серьезная ошибка, учитывая, что f() — функция не возвращающая значения.
Имхо, компилятор не должнен пропускать подобных ляпов.
Re[3]: gcc и определение функций
От: zaufi Земля  
Дата: 09.08.06 09:51
Оценка:
Здравствуйте, Bless, Вы писали:

MS>>Перегружать функции в C++ можно только по аргументам, но не по возвращаемым значениям.

MS>>Отсюда следует, что возвращаемое значение не участвует в формировании имени функции на этапе компиляции.
MS>>Поэтому никаких проблем с точки зрения линкера нет.

B>Дык, я не собирался ее перегружать! Просто хочу использовать функцию из одного .cpp в другом, для чего вынес ее объявление в .h . Я только начинающий в с++, но кажется в данном случае делал все правильно. И я очень удивлен, что компилятор не предупредил меня, что я опечатался и типы возвращаемых значений объявлений функции в head.h и head.cpp не совпадают!

B>Ведь строчка
B>
B> x=f();
B>

B>в main.cpp — серьезная ошибка, учитывая, что f() — функция не возвращающая значения.
B>Имхо, компилятор не должнен пропускать подобных ляпов.

варнинги включи при компиляции
-Wall
Re[4]: gcc и определение функций
От: Аноним  
Дата: 09.08.06 09:58
Оценка:
Z>варнинги включи при компиляции
Z>-Wall

Они включены.
Re[3]: gcc и определение функций
От: MShura  
Дата: 09.08.06 12:44
Оценка:
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 другая точка зрения. Он грязно ругается на стадии линковки.
Может, это все-таки баг?
Re[5]: gcc и определение функций
От: MShura  
Дата: 09.08.06 13:52
Оценка: 1 (1)
А>А вот у Microsoft Visual C++ 2003 другая точка зрения. Он грязно ругается на стадии линковки.
А>Может, это все-таки баг?

У MS возвращаемое значение влияет на генерацию уникального имени, что позволяет отлавливать такие ошибки.
Это также должно позволять перегружать функции только по возвращаемому значению.
Однако как показывает твой пример это не переносимо.
Re: gcc и определение функций
От: Аноним  
Дата: 09.08.06 15:28
Оценка:
Здравствуйте, Bless.

Сделай так и тебя уматерят по полной программе

head.h
#pragma once
double f();


head.cpp
#include "head.h"
#include <iostream>
using namespace std;
void f(){
  cout<<"double f()"<<endl;

}


А линковщику действительно на возвращаемый тип данных наплевать
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.