简体   繁体   English

定义中的const值参数是否真的是C ++的声明?

[英]Is the const value parameter in definition but not declaration really C++?

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: 下面是一些简单的测试代码,用于说明我在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. 当使用g ++编译时,它会编译,链接并执行运行时的预期。 You can also add a ++a; 你也可以添加++ a; in testy::lame() and the compiler will complain about changing a read-only variable (as it should). 在testy :: lame()中,编译器会抱怨更改只读变量(应该如此)。

However when I compile using CC, I get the following linker error: 但是当我使用CC编译时,我收到以下链接器错误:

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. 用nm和C ++过滤检查目标代码,我发现g ++版本创建了一个testy :: lame(int)符号,而CC创建了testy :: lame(const int),因此链接器错误。

I looked it up in Stroustrup's book, but can't find this technique mentioned (doesn't mean it's not there!); 我在Stroustrup的书中查了一下,但是找不到这种技术(并不意味着它不存在!); so is this really a compiler bug, or just a hack that works everywhere else but Solaris? 那么这真的是一个编译器错误,还是除了Solaris以外的其他地方都可以运行的hack?

This looks like a compiler problem in CC . 这看起来像CC的编译器问题。 The C++ standard says (in 13.1 Overloadable declarations): C ++标准说(在13.1可重载声明中):

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. 仅存在或不存在const和/或volatile的参数声明是等效的。 That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called. 也就是说,在确定声明,定义或调用哪个函数时,将忽略每个参数类型的const和volatile类型说明符。

But there are const / volatile modifiers that can participate in overloading, as the standard mentions shortly afterwards: 但是有一些const / volatile修饰符可以参与重载,不久后标准会提到:

Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; 仅以这种方式忽略参数类型规范最外层的const和volatile类型说明符; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations. 埋在参数类型规范中的const和volatile类型说明符很重要,可用于区分重载的函数声明。

The 'const' in the 'const int' parameter should be ignored by the compiler. 编译器应忽略'const int'参数中的'const'。 However, the difference between the declaration and the definition is bad style, to say the least. 然而,至少可以说,声明和定义之间的差异是不好的风格。

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. 它不是const的函数,而是一个参数,并且您在定义中进行添加。 Thus, the const you actually added affects only the implementation 因此,您实际添加的const仅影响实现

See this question . 看到这个问题

See C++ Coding Standards by Alexandrescu #15. 请参阅Alexandrescu#15的C ++编码标准。 This should work according to him. 这应该对他有用。 The const prevents the implementer of the function from changing the input variable. const阻止函数的实现者更改输入变量。 IMO the variable should remain const inside the function. IMO变量应该在函数内保持const。 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. 由于这在这里不起作用,我建议我的类在原型和实现中使用(const int a)。 I am a big fan of using techniques that work for all compilers. 我非常喜欢使用适用于所有编译器的技术。

I would always match the const on both declaration and definition. 我总是在声明和定义上匹配const This would reduce any problems because the signatures would match then. 这将减少任何问题,因为签名将匹配。

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. constvoid func1(const int)对函数没有任何影响,因为int是通过值传递的---是int的副本,并且只有函数调用时该副本才存在。 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. 你可能void func2(const char*)const很重要。 But you have to recognized that is different from void func3(char* const) . 但你必须认识到与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' 在后者中,它是指针(无关紧要)'const'

是的,const int与int不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM