定义中而非声明中的 const 值参数真的是 C++ 吗?

2023-11-29

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

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


这看起来像是编译器问题CC。 C++ 标准规定(在 13.1 可重载声明中):

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

但是这里有const/volatile可以参与重载的修饰符,正如标准随后不久提到的:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定义中而非声明中的 const 值参数真的是 C++ 吗? 的相关文章

随机推荐