我正在查看前面问题中给出的代码,其中包括基本如下的代码:
bool (*uninitializedFunctionPointer)(int, int);
typedef std::multimap<int, std::string, bool(*)(int, int)> MultiMapType;
MultiMapType myMap(uninitializedFunctionPointer);
请注意(顾名思义)uninitializedFunctionPointer是一个未初始化的函数指针,它被传递到myMap的构造函数中。奇怪的是,当我用g 4.8.4和Wall-Werror编译这段代码时,它没有报告任何警告。但是,它确实报告了类似代码的错误:
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!
我去了
multimap
的cp首选项留档,看到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);
}
这将导致调用a_function()
,无论对func
的赋值是发生在doThings()
的调用之前还是之后。如果函数定义在不同的编译单元中,并且编译器对此类事情发出警告,则上述代码在某些情况下会发出虚假警告。
有类似的技术涉及将引用或指针存储为返回对象成员的函数,调用方稍后将使用该函数。如果这样一个对象的构造函数使用传递的引用初始化常量引用或指针,则不需要我在这里使用的const\u cast。
开发人员使用此类技术是否是一个好主意是另一回事——我当然认为上述技术很差。但是使用此类技术的开发人员倾向于直言不讳地抱怨“虚假”警告——包括在一些商业库中——因此编译器供应商宁愿不发出警告。
问题内容: 该程序给出6作为输出,但是当我取消注释第9行时,输出为5。为什么?我认为ba不应更改,主要应保持5。 问题答案: 在Java中传递对象时,它们将作为in 方法中引用的参考含义对象和method 中的参数传递,它们都指向同一对象,因此,当您将值更改为6时,它将反映在方法中。 现在,当您尝试执行此操作时,您将指向另一个对象,但仍指向您在方法中创建的对象,因此更新的值6在main方法中不可见
问题内容: 我正在尝试学习log4j,所以我只是尝试做一些非常简单的事情。 但是做完之后我得到了; 你知道我错了吗? 谢谢你们 问题答案: 您在类路径中缺少或。 您可以使用 但是请注意,这只会登录到System.out,因此不建议这样做。您实际上应该使用上面的文件之一,然后将其写入日志文件。 一个非常简单的例子是
此代码取自IncludeOS github页面。我对它进行了一些修改,使其在编译时不需要其他头文件 find函数有点过于冗长,所以我想简化它。但修改后,代码的行为与我预期的不同。 这里有一个简短的解释。此代码用于解析HTTP头。标题字段是名称-值对。它表示为向量 在函数中,四个元素附加到字段中。不应该在字段中找到。但是返回true。 我试图用gdb跟踪错误。但我迷失在产出的海洋中。我确实发现了一条
我有下面的代码,它基本上映射了一个
问题内容: 我当时在Swinject上工作,但问题困扰着我。我已经整整一天都被困在那里。我怀疑这是由于Swift是一种静态类型的语言,但我不确定。 我在这个操场上总结了我的问题 我尝试了不同的解决方案,例如test.self或type(of:test),但它们都不起作用。 所以我想我不能用提供为变量的通用参数来调用函数? 问题答案: 与 协议元类型有两种。对于某些协议和符合类型: A 描述协议本身
问题内容: 我对通过Go中的引用和值传递感到困惑。 我已经看到了在类型前面的*的解释。 在类型名称前面表示已声明的变量将存储该类型的另一个变量的地址(而不是该类型的值)。 这对我来说毫无意义。 在Java中,如果我将数据库实例传递给函数,我会这样做 但是在go示例中,我已经像这样通过了。 为什么我们需要在类型前面加上星号? 根据这份备忘单,我发现了。 func PrintPerson(p * Pe