Reputation: 1329
I have a source that tells me:
The source file that defines a function should include the header that contains that function’s declaration. That way the compiler will verify that the definition and declaration are consistent.
I'm not sure how this is right, what type of "consistency" are we talking about? Because if the definition and declaration weren't consistent in return type or argument type/number, the compiler would just think I was declaring a separate function and wouldn't verify anything at all.
E.g. If I had a header file test.h:
void func();
And a source file testsource.cpp:
#include <iostream>
#include "test.h"
using namespace std;
void func(int x){
cout << "Hello StackOverflow" << endl;
}
If I were to run this program the compiler would just think func() and func(int) were different functions and wouldn't throw up a fuss about consistency. What type of consistency is it referring to?
Upvotes: 3
Views: 310
Reputation: 16997
Because if the definition and declaration weren't consistent in return type or argument type/number, the compiler would just think I was declaring a separate function ...
This is true. Both in the sense that the compiler would just think this, and in the sense that it could very well be that you are declaring (and defining) a separate function. Perfectly valid as far as the language is concerned.
... and wouldn't verify anything at all.
This is not entirely true. There is still something the compiler can verify. While it cannot complain (in your example) that the func(int)
definition does not match the func()
declaration, it can complain/warn that the func(int)
definition does not match any declaration.
The goal is to catch mismatches that are likely mistakes. A non-inline
function with external linkage normally–if good practices are followed–should be declared (in a header) before it is defined (in a source file). If it is not, then there is reason to think the programmer made a mistake. Some compilers can be asked to issue a warning if this happens.
(Since this question is old, I did some digging. While I don't know exactly when this option was added, it was available in gcc 4.4.7, which was released 2012-03-13, three years before this question was asked. So this is a valid answer both now and when the question was asked.)
For gcc, the option is -Wmissing-declarations
(which is not included in -Wall -Wextra
, possibly because the setup is not wrong, just probably unintended):
Warn if a global function is defined without a previous declaration. Do so even if the definition itself provides a prototype. Use this option to detect global functions that are not declared in header files. In C, no warnings are issued for functions with previous non-prototype declarations; use
-Wmissing-prototypes
to detect missing prototypes. In C++, no warnings are issued for function templates, or for inline functions, or for functions in anonymous namespaces.
Compiling your example code with this warning enabled gives
warning: no previous declaration for 'void func(int)' [-Wmissing-declarations]
so you know to double-check your declaration.
Upvotes: 1
Reputation: 9434
An interesting question. Your "source" [I assume that's a person or a book, or...] is wrong. Even though it's a common convention to have function declarations in a header file with the same base name as the file contain the function body, there's no requirement to do so.
Other than, of course, good coding standards.
You are correct, two functions with the same name but different arguments are perfectly acceptable -- as is declaring a function but never defining it (as long as you never call it.)
The C++ compiler does not keep you from shooting yourself in the foot, but good coding practices do.
Now that you edited the quote from the book into the question, I can point out that the quote says "should" not "must". The common-sense usage is neither mandated nor enforced by the language. It is simply good programming practice.
Also note that lint-type programs may well detect and complain about this, even though the compiler doesn't.
Upvotes: 3
Reputation: 11545
If you have another compilation unit that depends on your func
, say, a bar.cpp
defined this way:
#include "test.h"
void bar()
{
func();
}
This compilation unit imports your header and the compiler will assume that there will be another object file that defines whatever is declared in that test.h
header.
Now, if you only had your testsource.cpp
define a different function, instead (the one with different function signature), the compiler at this stage will complain of a linking error: the symbol func()
referred to in bar.cpp
cannot be found anywhere in its link inputs!
Upvotes: 1