如何阻止GCC消除if(0) block中的代码?
当我使用Visual Studio时,我的一种调试技巧是将这样的代码放在我的程序中:
if (0)
do_some_debug_printing_and_checking();
Run Code Online (Sandbox Code Playgroud)
然后,当遇到断点时,我单击do_some_debug_printing_and_checking()行,选择"set next statement"并强制执行.
当我使用gcc/gdb作为后端时,"set next statement"不再起作用,因为GCC只是从if(0)语句中删除代码.
我当然使用-O0标志来禁用优化.我也尝试了-fno-dce -fno-tree-dce标志来显式禁用死代码消除,但它没有效果:if(0)的内容在二进制文件中不存在而且我不能使用set next跳进去的声明.
有没有什么好方法告诉gcc禁用if(0)内容的消除?
编辑:
感谢"附加变量"解决方法,但有两件事我不喜欢它:
真的,绝对没有选择让GCC保留死代码吗?
我使用每用户Win32加密密钥容器(通过.Net RSACryptoServiceProvider类)来存储用于在密码管理器中解密存储密码的私钥.
这个私钥存储的安全性如何?显然,从同一个用户帐户运行的任何程序都可以访问它.但是密钥是否实际上是根据用户的密码加密的?
我可以假设只有用户登录后才能访问私钥吗?或者服务(或其他帐户)是否仍然可以提取密钥?计算机管理员可以不知道用户的密码提取它吗?可以通过使用管理帐户重置用户密码来提取密钥吗?如果计算机被盗并且攻击者可以访问硬盘(但不知道用户的密码),他可以提取私钥吗?如果用户已锁定会话,攻击者是否可以使用管理帐户/内核驱动程序从内存中提取密钥?
PS我知道'主密钥'模式,但在我的情况下这是不可接受的,所以我需要以最安全的方式存储密码.
我正在制作一个跨平台的库,在几个平台上实现几个基本原语.为了验证基元(即类)的每个实现都提供了所有平台上所需的核心成员,我使用以下构造:
template<typename _Ty> int _MethodVerifyHelper(_Ty);
#define ENSURE_MEMBER_DECL(className, methodName, returnType, ...) typedef char __PROTOTYPE_VERIFIER__[sizeof(_MethodVerifyHelper<returnType (className::*)(__VA_ARGS__)>(&className::methodName))]
Run Code Online (Sandbox Code Playgroud)
然后我写这样的东西:
ENSURE_MEMBER_DECL(Event, TryWait, bool, unsigned);
Run Code Online (Sandbox Code Playgroud)
因此,如果Event类没有bool TryWait(unsigned)方法,我们将在这里得到一个编译错误.
问题是:在C++中是否有类似的语法来声明指向构造函数的指针?我希望有一个语句,如果一个类没有提供给定参数类型的构造函数,则会导致编译时错误.
有什么方法可以避免MyMethodDelegate在这样的场景中明确声明?
bool MyMethod(string x)
{
//...
}
BeginInvoke(new MyMethodDelegate(MyMethod), x);
Run Code Online (Sandbox Code Playgroud)
我知道 lambdas a-la ()=>MyMethod(x),但是有时我想避免它们,因为它们会破坏编辑并继续。
编辑:只是BeginInvoke(MyMethod, x)不起作用:
The best overloaded method match for 'System.Windows.Forms.Control.BeginInvoke(System.Delegate, params object[])' has some invalid arguments
Argument 1: cannot convert from 'method group' to 'System.Delegate'
Argument 2: cannot convert from 'string' to 'object[]'
Run Code Online (Sandbox Code Playgroud)
BeginInvoke 定义如下:
public IAsyncResult BeginInvoke(Delegate method, params object[] args);
Run Code Online (Sandbox Code Playgroud)
它没有指定任何特定的委托类型,因此编译器无法检测从哪个委托类型实例化 BeginInvoke(MyMethod. x)