C++ 添加额外的const限定是否会破坏功能(假设编译顺利)?
当我尝试为自己的代码应用const正确性时,我通常必须在其他模块(由其他程序员编写)中的函数定义中添加C++ 添加额外的const限定是否会破坏功能(假设编译顺利)?,c++,testing,compilation,constants,C++,Testing,Compilation,Constants,当我尝试为自己的代码应用const正确性时,我通常必须在其他模块(由其他程序员编写)中的函数定义中添加const限定,以便在自己的代码中使用这些函数。() 我一直认为,如果一切都编译得很好,这可能会导致功能中断,因为const标签只在编译时起作用 然而,有一天,我的一位同事坚持说,在提交添加了const标签的代码之前,我应该重新运行所有自动测试,我认为编译这些代码就足够了 他有道理吗?有没有一种方法可以应用常量正确性来破坏现有的功能 编辑:可能需要注意的是,通常,我只需要对函数的指针参数执行此操
const
限定,以便在自己的代码中使用这些函数。()
我一直认为,如果一切都编译得很好,这可能会导致功能中断,因为const
标签只在编译时起作用
然而,有一天,我的一位同事坚持说,在提交添加了const
标签的代码之前,我应该重新运行所有自动测试,我认为编译这些代码就足够了
他有道理吗?有没有一种方法可以应用常量正确性来破坏现有的功能
编辑:可能需要注意的是,通常,我只需要对函数的指针参数执行此操作(例如
Something-getSomething(Object*pObj)
toSomething-getSomething(const-Object*pObj)
。我不会更改返回类型或方法常量,因为这对客户端代码来说不是问题。它们确实有道理
const
的变量中丢弃const
属性,则程序行为未定义。如果添加const
限定,则可能会将其引入代码中常量
引用的函数传递匿名临时变量,但如果函数接受非常量
引用,则行为未定义。许多编译器允许使用非常量
(可能是偶然的,尽管有些编译器甚至将其称为扩展).表面上看,修复此问题对每个人都有好处,但您可能正在删除运行时依赖的未定义行为构造添加
const
s的一个可能问题是以后更改变量时可能出现未定义的行为(在编译器无法再阻止它的情况下)。如果f是常数呢
float f = 1.0;
//do something with f
readFromBinaryFile((char *)(&f), sizeof(f));
//do another something with f
//...
void readFromBinaryFile(char *c, size_t s)
{
//... fill c
}
因为常量方法可能不同于非常量方法
class C
{
public:
int& get() { return i; }
int get() const { return i; }
private:
int i = 42;
};
您可能有不同的行为:
C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // true
鉴于
const C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // not true.
到目前为止,您得到的所有答案似乎都在谈论将
const
添加到变量。我将您的问题理解为将const
限定添加到成员函数。您能否澄清一下您添加的const
类型?如果您有测试,您应该始终运行它们如果您没有测试,那么您应该始终运行它们创建它们。嗯,有没有工具可以扫描代码并指出您可以/应该在哪里添加const
?当然,我总是在提交自己的代码时运行测试。但是运行所有测试大约需要3个小时,这对于为case(3)添加一些const标签来说似乎太多了这样的代码应该是格式不正确的,而不是未定义的。VC++是坏的。哪些编译器包含在“许多编译器”中?我并不反对你的答案,但是,澄清一下,(1)是否意味着使用const_cast
总是会产生未定义的行为?你在第4点。@Bathsheba“3.9.2.3.指向布局兼容类型的cv合格版本和cv不合格版本(3.9.3)的指针应具有相同的值表示和对齐要求(3.11)”,因此,情况(1)仅适用于const_cast
和等效版本(OP未提及)。似乎(3)和(4)是错误的,除了编译器不是C++编译器之外,哪一个是(2)--意外地删除了重载并用重写替换它。还缺少一种可能性,即在您const
ify一个参数后,函数将分派到不同的重写;虽然这种重写开关不应更改功能,但有时现有代码很糟糕。感谢您提供了一个具体的示例well,即 true
和不编译
;)您可以让它工作,但不能使用原始&
:&
不能直接应用于临时int
。您可以将c.get()
捕获到引用中,然后测试:常量int&a=c.get();常量int&b=c.get();断言(&a=&b)
@Yakk:Idea就在那里:)不管怎样,已经修复了。