是否有任何情况下,缺少 a#include会在运行时破坏软件,而构建仍在进行中?
换句话说,有没有可能
#include "some/code.h"
complexLogic();
cleverAlgorithms();
Run Code Online (Sandbox Code Playgroud)
和
complexLogic();
cleverAlgorithms();
Run Code Online (Sandbox Code Playgroud)
两者都会成功构建,但行为不同吗?
joh*_*ohn 41
是的,这是完全可能的。我确信有很多方法,但假设包含文件包含一个称为构造函数的全局变量定义。在第一种情况下,构造函数会执行,而在第二种情况下不会。
将全局变量定义放在头文件中是一种糟糕的风格,但这是可能的。
pas*_*sbi 34
是的,这是可能的。
与#includes有关的一切都发生在编译时。但是编译时的事情可以在运行时改变行为,当然:
some/code.h:
#define FOO
int foo(int a) { return 1; }
Run Code Online (Sandbox Code Playgroud)
然后
#include <iostream>
int foo(float a) { return 2; }
#include "some/code.h" // Remove that line
int main() {
std::cout << foo(1) << std::endl;
#ifdef FOO
std::cout << "FOO" std::endl;
#endif
}
Run Code Online (Sandbox Code Playgroud)
使用#include,重载解析会找到更合适的foo(int),因此打印1而不是2. 此外,由于FOO已定义,它还会额外打印
FOO.
这只是我立即想到的两个(不相关的)例子,我相信还有更多。
Cor*_*ica 15
只是为了指出微不足道的情况,预编译器指令:
// main.cpp
#include <iostream>
#include "trouble.h" // comment this out to change behavior
bool doACheck(); // always returns true
int main()
{
if (doACheck())
std::cout << "Normal!" << std::endl;
else
std::cout << "BAD!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
进而
// trouble.h
#define doACheck(...) false
Run Code Online (Sandbox Code Playgroud)
这可能是病态的,但我遇到过一个相关的案例:
#include <algorithm>
#include <windows.h> // comment this out to change behavior
using namespace std;
double doThings()
{
return max(f(), g());
}
Run Code Online (Sandbox Code Playgroud)
看起来无害。尝试调用std::max。但是,windows.h 将 max 定义为
#define max(a, b) (((a) > (b)) ? (a) : (b))
Run Code Online (Sandbox Code Playgroud)
如果这是std::max,这将是一个普通的函数调用,它计算一次 f() 和一次 g()。但是在 windows.h 中,它现在计算 f() 或 g() 两次:一次是在比较期间,一次是为了获取返回值。如果 f() 或 g() 不是幂等的,这可能会导致问题。例如,如果其中一个恰好是一个每次返回不同数字的计数器......
| 归档时间: |
|
| 查看次数: |
2403 次 |
| 最近记录: |