检查我的 const 变量是否尚未在外部修改
Checking if my const variable has not been modified externally
我现在的问题是,如果我使用 const
声明了一个常量,我读到它可以在外部修改(可能是通过连接到系统的设备(。我想知道是否可以检查我的常量是否已被修改。 当然,我会尝试这样的事情:
const double PI = 3.1412 //blah blah blah
// ...
if (PI == 3.1412) {
// do something with PI
}
这显然不会编译,因为常量不能是左值。
我该怎么做?还是不可能(如果做不到,我不想浪费时间(?
谢谢。
首先,为什么你的示例不编译? 如果你不能比较常量,它们就有点没用了。
我会将其归类为浪费时间。 如果程序外部的东西正在修改你的内存,那么有什么可以阻止它修改你存储比较的内存呢? 在您的示例中,该测试可能失败不是因为PI
更改了,而是因为3.1415
更改了...毕竟,这个数字存储在某个地方。
如果您的程序更改了 PI
的值,那么它就被破坏了,并且您无法确定测试无论如何都能可靠地工作。 这是坚定的未定义的行为,所以任何事情都会发生。 这很像测试引用参数是否引用空...一个定义良好的程序不可能导致测试失败,如果它可以通过,你也不能确定程序是否处于运行状态,所以测试本身就是浪费时间。
无论哪种情况,编译器都可能会认为测试是浪费时间,并将其全部删除。
现在,有一种情况与您最初所说的略有不同,这可能是您的消息来源所指的。 请考虑以下代码:
void external_function();
void internal_function(const int& i) {
cout << i << "...";
external_function();
cout << i;
}
在internal_function
内,编译器不能假设两个输出是相同的。 i
可以是对实际上没有const
的整数的引用,external_function
可以改变它。 这里的关键区别在于i
是一个参考,而在原始问题中PI
是一个常量值。
int pi = 3;
void external_function() { pi = 4; }
void internal_function(const int&);
int main() {
internal_function(pi);
}
这将导致3...4
被打印出来。 即使i
是一个常量引用,编译器也必须假设它可能会更改,因为它看不到的东西可能会更改它。
在这种情况下,这种测试在某些情况下可能是有用的。
void internal_function(const int& i) {
const int original_i = i;
cout << i << "...";
external_function();
cout << i << endl;
if(i != original_i) cout << "lol wut?" << endl;
}
在这种情况下,测试很有用。 original_i
保证没有改变[如果有,请参阅本答案的前半部分],如果i
改变了,断言将失败。
常量折叠在这里很重要。使用示例代码,
const double PI = 3.1412; //blah blah blah
if (PI == 3.1412) {
}
文本实际上可能共享常量的存储空间。
您似乎想要某种"保险"或"篡改检测"。
为此,您必须使用某种证书对二进制文件进行自签名。但是,通过足够的逆向工程,可以颠覆签名的验证。
因此,您实际上需要一个受信任的内核函数来在执行之前验证二进制文件。开源内核似乎具有适当的同行评审和交叉检查的好处。该内核确实需要 TPM 硬件来提供帮助。然后,您将归结为物理安全性(您必须信任硬件供应商和托管位置的物理安全性(。
此外,还需要NX内核功能(或像Win32 DEP(一样,以防止执行可写内存。相反,您需要对可执行段进行内核保护(无论如何,通常都是这种情况,以允许共享内存映射,IIRC(。
所有这些都引出了一个问题:你需要这种安全性做什么。根据答案,实施上述内容以及更多内容甚至可能是合理的。
$0.02
const
的要点是标识符是一个常量。如果有人使用const_cast
或其他技巧来破坏你的常量,那么他们的程序将具有未定义的行为。在实践中,我不会担心这一点。
,一旦你通过一些优化编译你的代码,编译器就会发出带有常量文字(如3.1412
(而不是变量名(如PI
(的机器代码。因此,机器代码很可能没有您在代码中使用的符号(即PI
(。
static const double PI = 3.14;
防止从使用此常量编译的其他模块修改此常量。OTOH,它不会避免使用十六进制编辑器或内存中更改此常量。
另一种解决方案(不推荐但可能(是使用
#define PI 3.14
而且,是的,您可以使用
M_PI
不断。看到这个问题
我假设必须修改 const 所在的实际内存空间才能修改。除非您有明确的理由/问题进行此类检查,否则我会说这不是必需的。我从来不知道有什么需要检查常量的值。
如果你有一个声明的非易失性const
变量,就没有合法的方式可以在外部修改它。
写入 const
变量是未定义的行为。在另一个翻译单元中声明extern double PI;
将声明与您声明的变量不同的变量,因为您的变量具有内部链接,这意味着它只能在同一个翻译单元中重新声明。
即使它要声明相同的变量,那么行为也是未定义的(因为类型标识中的const
/non-const
不匹配(。
如果不调用未定义的行为,就无法更改常量变量。对此进行辩护是没有意义的。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 独立读取-修改-写入顺序
- 在函数内部的声明中初始化数组,并在外部使用它
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 在 C++ 中从类外部修改类的成员
- 如何跟踪通过外部代码修改类变量的所有位置
- 如何从类外部修改向量
- 保护外部数据文件免受未经授权的修改
- 如何创建外部不可修改的变量
- 检查文件是否在应用程序外部被修改
- 视觉获取链接错误:C++中的外部.如何访问在文件 A 中修改的变量的值.CPP在另一个文件 B .CPP中修改
- 使用外部条件修改序列操作
- 为什么在C++允许从外部修改常量对象的指针成员变量的内存?
- c++中未解析的外部函数:Visual c++对方法签名的修改与dll中修改的方法不同
- 从复制构造函数外部修改对象成员时导致向量内存损坏,但从复制构造函数内部修改时不会
- 检查我的 const 变量是否尚未在外部修改
- ' pthread '的运行函数如何修改外部变量
- cv::使用cv::imdecode后不修改外部数据