3

这类似于(但不同于)这个问题

下面是一些简单的测试代码来说明我在 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

当它使用 g++ 编译时,它会编译、链接并执行您在运行时所期望的操作。您还可以添加 ++a; 在 testy::lame() 中,编译器会抱怨更改只读变量(应该如此)。

但是,当我使用 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

用 nm 和 C++filt 检查目标代码,我发现 g++ 版本创建了一个 testy::lame(int) 符号,而 CC 创建了 testy::lame(const int) ,因此出现链接器错误。

我在 Stroustrup 的书中查到了它,但找不到提到的这种技术(并不意味着它不存在!);那么这真的是一个编译器错误,还是只是一个在 Solaris 之外的其他地方都可以使用的 hack?

4

7 回答 7

25

这看起来像是CC. C++ 标准说(在 13.1 可重载声明中):

仅在存在或不存在 const 和/或 volatile 方面不同的参数声明是等效的。也就是说,在确定声明、定义或调用哪个函数时,将忽略每个参数类型的 const 和 volatile 类型说明符。

但是有const/volatile修饰符可以参与重载,正如标准稍后提到的那样:

只有参数类型说明最外层的 const 和 volatile 类型说明符以这种方式被忽略;隐藏在参数类型规范中的 const 和 volatile 类型说明符很重要,可用于区分重载函数声明。

于 2009-04-20T14:48:08.600 回答
4

'const int' 参数中的 'const' 应该被编译器忽略。但是,声明和定义之间的区别至少可以说是糟糕的风格。

于 2009-04-20T14:47:43.953 回答
1

我的理解是这是允许的,因为它对调用者没有什么影响。不是 const 的函数,而是一个参数,您正在定义中进行添加。因此,您实际添加的 const 仅影响实现

看到这个问题

于 2009-04-20T14:48:26.463 回答
0

我总是匹配const声明和定义。这将减少任何问题,因为签名会匹配。

于 2009-04-20T14:43:39.080 回答
0

constis对void func1(const int)函数没有任何影响,因为 int 是按值传递的——创建了 int 的副本,并且该副本仅在函数调用期间存在。您是否更改该副本与任何事情无关。

您可能对 in很重要void func2(const char*)这一事实感到困惑。const但你必须认识到,不同于void func3(char* const). 前者是指向的字符不能改变;在后者中,它是(不相关的)'const'的指针

于 2009-04-20T15:21:39.660 回答
0

请参阅 Alexandrescu #15 的 C++ 编码标准。这应该按照他的方式工作。const 防止函数的实现者更改输入变量。IMO 变量应在函数内保持不变。如果您需要一个变量,请声明一个。优化器将为您摆脱它。

int temp = a;

由于这在这里不起作用,我建议我的班级在原型和实现中都使用 (const int a)。我非常喜欢使用适用于所有编译器的技术。

于 2012-09-22T00:19:01.370 回答
-2

是的,const int 与 int 不同。

于 2009-04-20T14:45:16.877 回答