问题
This is similar to (but different from) this question.
Here is some simple test code to illustrate some weirdness I have discovered with Sun CC:
//---------------main.cpp
#include "wtc.hpp"
int main(int, char**)
{
testy t;
t.lame(99);
return 0;
}
//--------------wtc.hpp
#ifndef WTC_HPP_INCLUDED
#define WTC_HPP_INCLUDED
class testy
{
public:
void lame(int );
};
#endif
//---------------wtc.cpp
#include <iostream>
#include "wtc.hpp"
void testy::lame(const int a)
{
std::cout << "I was passed " << a << "\n";
}
//---------------makefile
#CXX=CC
CXX =g++
#CXXFLAGS= -g
CXXFLAGS= -g3 -Wall -Werror
OBJECTS=$(patsubst %.cpp,%.o,$(wildcard *.cpp))
all : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $^
.PHONY: clean
clean :
rm *.o
When this was compiled using g++ it compiles, links and does what you would expect when run. You can also add a ++a; in testy::lame() and the compiler will complain about changing a read-only variable (as it should).
However when I compile using CC, I get the following linker error:
CC -g -c -o main.o main.cpp
CC -g -c -o wtc.o wtc.cpp
CC -g -o all main.o wtc.o
Undefined first referenced
symbol in file
void testy::lame(int) main.o
ld: fatal: Symbol referencing errors. No output written to all
make: *** [all] Error 1
checking the object code with nm and C++filt, I find that the g++ version creates a testy::lame(int) symbol, whereas CC creates testy::lame(const int) , hence the linker error.
I looked it up in Stroustrup's book, but can't find this technique mentioned (doesn't mean it's not there!); so is this really a compiler bug, or just a hack that works everywhere else but Solaris?
回答1:
This looks like a compiler problem in CC
. The C++ standard says (in 13.1 Overloadable declarations):
Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.
But there are const
/volatile
modifiers that can participate in overloading, as the standard mentions shortly afterwards:
Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations.
回答2:
The 'const' in the 'const int' parameter should be ignored by the compiler. However, the difference between the declaration and the definition is bad style, to say the least.
回答3:
My understanding is that this is allowed because it makes little difference for the caller. It is not the function that is const, but rather a parameter, and you are making the addition in the definition. Thus, the const you actually added affects only the implementation
See this question.
回答4:
I would always match the const
on both declaration and definition. This would reduce any problems because the signatures would match then.
回答5:
The const
is void func1(const int)
has no affect whatsoever on the function, since the int is passed by value --- a copy of the int is made, and that copy lives only as long as the function call. Whether or not you change that copy has no bearing on anything.
You are probably confused by the fact that in void func2(const char*)
the const
is significant. But you have to recognized that is different from void func3(char* const)
. In the former, it's the character pointed to that cannot change; in the latter, it's the pointer that is (irrelevantly) 'const'
回答6:
See C++ Coding Standards by Alexandrescu #15. This should work according to him. The const prevents the implementer of the function from changing the input variable. IMO the variable should remain const inside the function. If you need a variable, declare one. The optimizer will get rid of it for you.
int temp = a;
Since this does not work here I am advising my class to use the (const int a) in both the prototype and implementation. I am a big fan of using techniques that work for all compilers.
回答7:
Yes, a const int is not the same as an int.
来源:https://stackoverflow.com/questions/768588/is-the-const-value-parameter-in-definition-but-not-declaration-really-c