gpt4 book ai didi

c++ - 为什么 g++ 在通过 const 引用将未初始化的值传递给函数时不报告警告?

转载 作者:太空狗 更新时间:2023-10-29 20:36:29 25 4
gpt4 key购买 nike

我正在查看给出的代码 in this earlier question ,其中包含的代码基本上如下:

bool (*uninitializedFunctionPointer)(int, int);
typedef std::multimap<int, std::string, bool(*)(int, int)> MultiMapType;
MultiMapType myMap(uninitializedFunctionPointer);

请注意(顾名思义)uninitializedFunctionPointer 是一个未初始化的函数指针,它被传递到 myMap 的构造函数中。奇怪的是,当我用带有-Wall -Werror 的g++ 4.8.4 编译这段代码时,它编译这段代码时没有报告任何警告。但是,它确实报告了以下类似代码的错误:

bool (*uninitializedFunctionPointer)(int, int);
uninitializedFunctionPointer(137, 42);

由于调用函数指针会触发警告,但将其传递给 multimap 构造函数却不会,我认为 g++ 根本不关心将未初始化的值作为参数传递给函数。但是,此代码确实会触发警告:

void doSomething(bool (*function)(int, int)) {
function(137, 42); // Problem if 'function' is uninitialized
}

bool (*uninitializedFunctionPointer)(int, int);
doSomething(uninitializedFunctionPointer); // Warning!

我去了cppreference documentation for multimap并看到 multimap 构造函数通过 const 引用接收其比较器,所以我尝试编写以下代码:

typedef bool (*FunctionType)(int, int);
void doSomething(const FunctionType &function) {
function(137, 42); // Problem if 'function' is uninitialized
}

bool (*uninitializedFunctionPointer)(int, int);
doSomething(uninitializedFunctionPointer);

而且,令人惊讶的是,这段代码编译完全没有任何警告。我认为这可能与函数指针有关,但看起来并非如此!这是仅使用普通旧整数的相关代码:

void doSomething(const int &value) {
std::cout << value << std::endl; // Problem if value is uninitialized
}

int uninitializedInt;
doSomething(uninitializedInt);

此代码编译时根本没有警告,即使启用了 -Wall

我知道编译器不需要对所有类型的编程错误发出警告,但是 g++ 会检测到直接使用未初始化的变量并尝试将未初始化的变量传递给函数,这似乎非常不寻常值,但在通过 const 引用将未初始化的变量传递给函数时不会报告问题。

是否有令人信服的理由说明为什么 g++ 不会在此处报告警告?比如,是否有合理的代码可以通过 const 引用将未初始化的变量传递给函数而不触发某种未定义的行为?或者这只是编译器的疏忽?

最佳答案

问题来了,因为给定一个引用,函数有可能存储一个指针或引用。

typedef bool (*FunctionType)(int, int);

FunctionType *stored_function;

void doSomething(const FunctionType &function)
{
stored_function = const_cast<FunctionType *>(&function);
}

void doSomethingElse(int a, int b)
{
(*stored_function)(a, b);
}

bool a_function(int, int)
{
// do something
return false;
}


int main()
{
FunctionType func;
doSomething(func);

func = a_function;

doSomethingElse(1,2);
}

这将导致 doSomethingElse() 调用 a_function(),无论对 func 的赋值发生在 调用之前还是之后>doSomething()。如果函数定义在不同的编译单元中,并且编译器对此类事情发出警告,则在某些情况下,像上面这样的代码会给出虚假警告。

还有一些类似的技术涉及函数将引用或指针存储为返回对象的成员,稍后将由调用者使用。如果此类对象的构造函数使用传递的引用初始化 const 引用或指针,则不需要我在此处使用的 const_cast

开发人员使用此类技术是否是个好主意是另一回事 - 我当然认为上述技术很差。但是使用此类技术的开发人员往往会直言不讳地提示“虚假”警​​告(包括在某些商业库中),因此编译器供应商宁愿不发出警告。

关于c++ - 为什么 g++ 在通过 const 引用将未初始化的值传递给函数时不报告警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38255085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com