Tag: gcc

为什么scanf对大浮点数输错了?

#include int main() { float k; scanf(“%f”, &k); printf(“%f”, k); } 在这个简单的程序中,当我输入一个包含最多8位数的数字时,它会正确显示。 但如果我超过8位,即对于输入123456789 ,输出为123456792 。 为什么会这样? 好有趣的事实是,如果我在123456789和123456796之间输入任何数字,那么它总是显示123456792 。 它是否与浮点数的8位小数精度有关?

为什么编译器会假设这些看似相等的指针有所不同?

看起来GCC有一些优化认为来自不同翻译单元的两个指针永远不会相同,即使它们实际上是相同的。 码: main.c中 #include #include int a __attribute__((section(“test”))); extern int b; void check(int cond) { puts(cond ? “TRUE” : “FALSE”); } int main() { int * p = &a + 1; check( (p == &b) == ((uintptr_t)p == (uintptr_t)&b) ); check(p == &b); check((uintptr_t)p == (uintptr_t)&b); return 0; } 公元前 int b __attribute__((section(“test”))); 如果我用-O0编译它,它会打印出来 TRUE […]

我们可以在几秒钟后强制退出C程序的执行

我们可以在几分之一秒(毫秒范围)或它使用的内存大小后强制退出C程序的执行吗? 这样,我想在无限循环中限制打印内容并限制缓冲区溢出。 我正在使用cygwin GCC4.3编译器,并希望将其作为PHP中的工具实现,它将C源作为输入并显示相应的输出。 PS – 1.我说毫秒因为我的C问题只涉及非常简单的算术/计算。 2.为了限制执行时间,php中的set_time_limit()将限制整个PHP脚本的执行时间,而不是分配给exec()的时间。

将变量放在特定地址会生成大型二进制文件

我必须将数组放在内存中的特定地址。 我正在使用GCC。 我声明变量如下: uint8_t __attribute__((section (“.mySection”))) buffer[1234]; 在链接器脚本中我得到了: MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 145K MYSEC (x) : ORIGIN = 0x20025000, LENGTH = 155K } 然后: .mySection : { *(.mySection); } > MYSEC 它当然是嵌入式系统(ARM)的代码。 通常我的程序需要22 KB,这个修改需要384 MB(!)。 我不明白为什么。 如果我删除__attribute__它再次需要22 KB。 我错过了什么? 使用的代码: […]

C /汇编:如何更改CPU寄存器中的单个位?

我是软件故障注入领域的新研究员,目前我的最终目标是编写一段能够改变CPU寄存器中单个位的代码。 我在考虑用C语言(在代码中包含一些程序集调用)。 考虑到这一点,我在Stack Overflow中找到了这个很棒的线程和关于如何访问32位CPU寄存器内容的简单示例: 是否可以在C中访问32位寄存器? 这样,我就能编写这个简单的代码: #include int main() { register int value; register int ecx asm(“ecx”); printf(“Contents of ecx: %d\n”, ecx); asm(“movl %%ecx, %0;” : “=r” (value) : ); //Assembly: this stores the ecx value into the variable value printf(“Contents of value: %d\n”, value); return 0; } 这似乎是对这个主题的一个很好的介绍,那里提供的答案给了我很好的见解和信息来源(我已经阅读了GCC文档),但现在我需要进一步,即我需要了解怎么能我更改了CPU寄存器中单个位的内容(或者至少,要启动,更简单一些:如何更改CPU寄存器值?)。 如果有人能给我一个提示或告诉我最合适的来源,我会非常感激。 最好的,并提前感谢,João PS:不知道这是否有帮助,但我正在使用CentOS 6.5 32位系统(虽然CPU是64位,更准确地说是Intel Pentium双CPU […]

如何在代码块上添加编译器标志

我一直在尝试编译一个我在网上找到的简单的multithreading代码,以学习如何multithreading。 要运行这段代码,我需要使用编译器标志: -pthread和-std=c++0x 。 但每当我尝试添加标志时,构建日志都不会显示它们被使用。 我已经尝试了一些在线的通用技巧,以使这些工作起作用,但它们都没有奏效。 有人可以帮忙吗? 我已经尝试了其他在线建议将编译器标志添加到代码块,但是当我这样做并检查构建日志时,它们都没有出现。

gcc:命令行参数在汇编代码中引用不同

我习惯看到(约定(A))引用的命令行参数: pushl %ebp movl %esp, %ebp movl (%ebp), %eax # argc movl 4(%ebp), %ebx # pointer to argv[0] string movl 8($ebp), %ecx # pointer to argv[1] string 有时,我看到列表的偏移量为8,这不是(主要)问题。 我在程序中注意到的是这个翻译和引用,我很困惑,得到argv[1] (约定(B)): movl 0xc(%ebp), %eax # pointer to a pointer to argv[0] (argc is at offset 8) addl $0x4, %eax # argv[1] is a pointer at offset […]

swprintf在xcode中使用unicode字符失败,但在visual studio中工作

在尝试转换某些现有代码以支持unicode字符时,会出现此问题。 如果我尝试将unicode字符(在本例中使用欧元符号)传递到任何* wprintf函数中,它将失败,但似乎只在xcode中。 相同的代码在visual studio中运行良好,我甚至能够让朋友在linux上使用gcc成功测试它。 这是违规代码: wchar_t _teststring[10] = L””; int _iRetVal = swprintf(_teststring, 10, L”A¥€”); wprintf(L”return: %d\n”, _iRetVal); // print values stored in string to check if anything got corrupted for (int i=0; i<wcslen(_teststring); ++i) { wprintf(L"%d: (%d)\n", i, _teststring[i]); } 在xcode中,对swprintf的调用将返回-1,而在visual studio中,它将成功并继续为3个字符(65,165,8364)中的每一个打印出正确的值。 我已经google了很长时间,很难找到解决方案,一个已出现多次的建议是使用如下调用: setlocale(LC_CTYPE, “UTF-8”); 我已尝试使用此函数的各种参数组合但没有成功,经过进一步调查,如果我尝试将语言环境设置为默认值“C”以外的任何值,则它似乎返回null。 我不知道还有什么可以尝试解决这个问题,而且它在其他编译器/平台上运行的事实让它更令人沮丧。 任何帮助将非常感激! 编辑:我想补充一点,当swprintf调用失败时,它会设置一个错误代码(92),定义为: #define EILSEQ 92 /* […]

如何在OS X上强制使用64位整数运算?

我试图在OS X 10.5.6上强制64位长整数。 在Apple MacBook Intel Core 2 Duo上运行。 这是我的c代码: #include int main() { long a = 2147483647; /*== 2^32 – 1*/ long aplus1; printf(“a== %d. sizeof(a) == %d \n”, a, sizeof(a)); aplus1 = a+1; printf(“aplus1 = %d \n”, aplus1); } 没有任何开关进行编译会产生以下结果: $ gcc testlong.c -o testlong ;./testlong a== 2147483647. sizeof(a) == 4 aplus1 = […]

C编译器是否能够跨目标文件进行优化?

我正在考虑标题与标题和源代码设计之间的关系。 我不确定标头和源是否允许编译器跨目标文件和链接进行优化? 内联优化?