x86和x64之间的浮点算术的差异

我偶然发现了在x86和x64的MS VS 2010版本之间完成浮点算术的方式不同(两者都在同一台64位机器上执行)。 这是一个简化的代码示例: float a = 50.0f; float b = 65.0f; float c = 1.3f; float d = a*c; bool bLarger1 = d<b; bool bLarger2 = (a*c)<b; 布尔bLarger1始终为false(在两个版本中d都设置为65.0)。 变量bLarger2对于x64为false,但对于x86为true! 我很清楚浮点算术和圆角效应正在发生。 我也知道32位有时使用不同的指令进行浮动操作而不是64位构建。 但在这种情况下,我错过了一些信息。 为什么bLarger1和bLarger2之间首先存在差异? 为什么它只出现在32位构建中?

如何将复合文字用于`fprintf()`具有任意碱基的多个格式化数字?

我想将多个数字转换为某种表示forms,然后使用*printf()说明符的标志,宽度和精度。 首选是避免全局或static缓冲区。 关键问题似乎是如何为每个转换后的数字提供char[] ? fprintf(ostream, “some_format”, foo(int_a, base_x), foo(int_b, base_y), …); 如何使用C11复合文字来解决这个问题? 如何使用C99(或更高版本)复合文字来解决这个问题?

x86的MOV真的可以“免费”吗? 为什么我不能重现这个呢?

我一直看到人们声称MOV指令可以在x86中免费,因为寄存器重命名。 对于我的生活,我无法在一个测试用例中validation这一点。 每个测试用例我尝试揭穿它。 例如,这是我用Visual C ++编译的代码: #include #include #include int main(void) { unsigned int k, l, j; clock_t tstart = clock(); for (k = 0, j = 0, l = 0; j < UINT_MAX; ++j) { ++k; k = j; // <– comment out this line to remove the MOV instruction l += j; } […]

嵌套函数在gcc中是坏事吗?

我知道嵌套函数不是标准C的一部分,但由于它们存在于gcc中(并且事实上gcc是我唯一关心的编译器),我倾向于经常使用它们。 这是坏事吗 ? 如果是这样,你能告诉我一些令人讨厌的例子吗? gcc中嵌套函数的状态是什么? 他们会被删除吗?

当变量超出范围时会发生什么?

在大多数托管语言(即具有GC的语言)中,超出范围的局部变量不可访问且具有更高的GC优先级(因此,它们将首先被释放)。 现在,C不是托管语言,超出范围的变量会发生什么? 我在C中创建了一个小测试用例: #include int main(void){ int *ptr; { // New scope int tmp = 17; ptr = &tmp; // Just to see if the memory is cleared } //printf(“tmp = %d”, tmp); // Compile-time error (as expected) printf(“ptr = %d\n”, *ptr); return 0; } 我正在使用GCC 4.7.3进行编译,上面的程序打印17 ,为什么? 何时/在什么情况下可以释放局部变量?

为什么空表达式在C / C ++中合法?

int main() { int var = 0;; // Typo which compiles just fine }

为什么scanf(“%d”,)不消耗’\ n’? 而scanf(“%c”)呢?

在这里 ,我在接受的答案中看到了这个陈述: 大多数转换说明符跳过前导空格,包括换行符,但%c不跳过。 对我来说,不清楚这种不同行为的基本原理,我会期待一个统一的行为(例如总是跳过或从不)。 我用这样的一段C代码遇到了这种问题: #include “stdio.h” int main(void){ char ch; int actualNum; printf(“Insert a number: “); scanf(“%d”, &actualNum); // getchar(); printf(“Insert a character: “); scanf(“%c”, &ch); return 0; } 交换两个scanf解决了问题,以及(注释) getchar ,否则第一次插入的’\n’将由第二个scanf消耗%c 。 我在linux和windows上测试了gcc,行为是一样的: gcc(GCC)4.7.2 20120921(Red Hat 4.7.2-2) 版权所有(C)2012 Free Software Foundation,Inc。 这是免费软件; 查看复制条件的来源。 没有保修; 甚至不适用于适销性或特定用途的适用性。 所以我的问题是:为什么%d和%c行为与scanf ‘\n’不同?

为什么gdb将sqrt(3)评估为0?

由Wolfram Alpha估算的3的平方根: 1.7320508075688772935274463415058723669428052538103806280558… 当我在C中执行sqrt(3)时,它的计算结果为0.为什么? 编辑4 :这是你如何在GDB中重现这个问题。 创建test.c如下: #include #include int main() { printf(“sqrt(3): %f\n”, sqrt(3)); return 0; } 编译: gcc -O0 -g -Wall -pedantic -ansi -lm -o test test.c 运行调试器: gdb test 在控制台输入: (gdb) break test.c:6 Breakpoint 1 at 0x400578: file test.c, line 6. (gdb) r Starting program: /home/pdedecker/Desktop/test Breakpoint 1, main () at test.c:6 […]

如何用gcc改变C程序的入口点?

如何更改用gcc编译的C程序的入口点? 就像在下面的代码中一样 #include int entry() //entry is the entry point instead of main { return 0; }

取消引用空指针在sizeof操作中有效

我遇到了一段代码片段,对我来说应该会因为分段错误而崩溃,但它可以毫无障碍地工作。 有问题的代码加上相关的数据结构如下(上面找到相关的评论): typedef struct { double length; unsigned char nPlaced; unsigned char path[0]; } RouteDefinition* Alloc_RouteDefinition() { // NB: The +nBags*sizeof.. trick “expands” the path[0] array in RouteDefinition // to the path[nBags] array RouteDefinition *def = NULL; return (RouteDefinition*) malloc(sizeof(RouteDefinition) + nBags * sizeof(def->path[0])); } 为什么这样做? 我认为char *的大小将解析为给定体系结构上指针的大小,但是在取消引用NULL -pointer时不应该崩溃和刻录?