我知道在所有C编译器实现背后都有一个标准,因此不应该有任何隐藏功能。尽管如此,我相信所有的C开发人员都有他们经常使用的隐藏/秘密技巧。
我知道在所有C编译器实现背后都有一个标准,因此不应该有任何隐藏功能。尽管如此,我相信所有的C开发人员都有他们经常使用的隐藏/秘密技巧。
奇怪的向量索引:
int v[100]; int index = 10;
/* v[index] it's the same thing as index[v] */
其他问题和问题会在程序员对执行模型做出假设时出现,这些行为在大多数C标准中都被指定为“依赖于编译器”的行为。
sscanf ( string, "%d%n", &number, &length );
string += length;
显然,您无法添加另一个答案,因此我在此包含第二个答案,您可以使用"&&"和"||"作为条件语句:
#include <stdio.h>
#include <stdlib.h>
int main()
{
1 || puts("Hello\n");
0 || puts("Hi\n");
1 && puts("ROFL\n");
0 && puts("LOL\n");
exit( 0 );
}
您好 ROFL
Gcc(C语言编译器)有一些有趣的功能可以启用,例如嵌套函数声明和 ?: 运算符的 a?:b 形式,如果 a 不为 false,则返回 a。
使用INT(3)在代码中设置断点是我一直以来最喜欢的方法。
我最喜欢 C 语言中的“隐藏”功能是在 printf 中使用 %n 将值写回堆栈。通常,printf 根据格式字符串从堆栈中弹出参数值,但 %n 可以将它们写回。
请查看第 3.4.2 节这里。可能会导致许多严重的漏洞。
使用枚举类型进行编译时假设检查: 虽然下面的示例比较简单,但对于具有可在编译时配置的常量的库来说非常有用。
#define D 1
#define DD 2
enum CompileTimeCheck
{
MAKE_SURE_DD_IS_TWICE_D = 1/(2*(D) == (DD)),
MAKE_SURE_DD_IS_POW2 = 1/((((DD) - 1) & (DD)) == 0)
};
#define CompilerAssert(exp) extern char _CompilerAssert[(exp)?1:-1]
) - Patrick Schlüter我最近发现了0位字段。
struct {
int a:3;
int b:2;
int :0;
int c:4;
int d:3;
};
这将提供一个布局
000aaabb 0ccccddd
将“:0;”替换为“without”。
0000aaab bccccddd
char
)上。#define ERR(name, fmt, ...) fprintf(stderr, "ERROR " #name ": " fmt "\n", \
__VAR_ARGS__)
这将会像这样使用
ERR(errCantOpen, "File %s cannot be opened", filename);
在这里,我还使用了字符串化操作符和字符串常量连接,其他功能我也非常喜欢。
变量大小的自动变量在某些情况下也很有用。这些特性被添加到C99中,并且在gcc中已经得到了长期支持。
void foo(uint32_t extraPadding) {
uint8_t commBuffer[sizeof(myProtocol_t) + extraPadding];