我正在为 LeetCode、Codeforces 等编程竞赛开发一个在线评委系统。对于大多数编程竞赛,C/C++ 中不允许使用内联汇编程序,因此我想在我的系统中添加相同的限制。
我想让GCC和G++在编译包含内联汇编的C/C++程序时产生错误,这样任何包含内联汇编的代码都会导致编译错误。
有办法实现吗?我应该将一些命令行参数传递给 GCC/G++ 吗?
注意:禁用内联汇编只是为了遵守规则,而不是出于安全考虑。
最佳答案
有没有办法在 GCC 中禁用内联汇编程序?
是的,有几种方法。
在编译器中关闭汇编
要在编译阶段执行此操作,请使用参数 -fno-asm
。但是,请记住,这只会影响 asm
而不会影响 __asm__
。
文档:
-fno-asm
Do not recognize "
asm
", "inline
" or "typeof
" as a keyword, so that code can use these words as identifiers. You can use the keywords "__asm__
", "__inline__
" and "__typeof__
" instead.-ansi
implies-fno-asm
.In C++ , this switch only affects the "
typeof
" keyword, since "asm
" and "inline
" are standard keywords. You may want to use the-fno-gnu-keywords
flag instead, which has the same effect. In C99 mode (-std=c99
or-std=gnu99
), this switch only affects the "asm
" and "typeof
" keywords, since "inline
" is a standard keyword in ISO C99.
定义宏
可以使用参数-Dasm=error -D__asm__=error
请注意,此结构是通用的。它的作用是创建宏。它的工作方式与 #define
非常相似。文档说:
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive. In particular, the definition will be truncated by embedded newline characters.
...
所以它所做的只是将 asm
或 __asm__
的出现更改为 error
。这是在预处理器阶段完成的。您不必使用 error
。只需选择任何不会编译的东西即可。
使用在编译期间触发的宏
如 zwol 的评论中所建议的,一种在编译阶段使用宏解决它的方法,您可以使用 -D'asm(...)=_Static_assert(0,"inline assembly not allowed")'
。如果存在名为 error
的标识符,这也将解决问题。
注意:此方法需要 -std=c11
或更高版本。
在使用gcc之前使用grep
另一种可能解决您的问题的方法是在编译之前在源代码树的根目录中执行 grep
:
grep -nr "asm"
这也会捕获 __asm__
但它可能会产生误报,例如,如果您有一个字符串文字、标识符或包含子字符串 "asm"
的注释。但在你的情况下,你可以通过禁止在源代码中的任何地方出现该字符串来解决这个问题。只需更改规则即可。
可能出现的意外问题
请注意,禁用程序集可能会导致其他问题。例如,我无法将 stdio.h
与此选项一起使用。系统头文件包含内联汇编代码是很常见的。
一种欺骗上述方法的方法
可以将字符串作为机器代码来执行。有关示例,请参见此答案:https://stackoverflow.com/a/18477070/6699433
上面链接中的一段代码:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
上面的代码只是为了快速了解如何欺骗 OP 规定的规则。它无意成为如何在现实中实际执行它的一个很好的例子。此外,代码不是我的。这只是我提供的链接中的简短代码引用。如果您有关于如何改进它的想法,请改为评论 4pie0:s 的原始帖子。
关于c++ - 有没有办法在 GCC 中禁用内联汇编程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55192591/