小编pip*_*ipe的帖子

C - 为什么ANSI只为外部标识符中的最小有效字符数指定了六个字符?

我有一个关于部分问题5.2.4.1翻译限制在第一American National Standard for Programming languages - C,也被称为ANSI/ISO 9899-1990,ISO/IEC 9899.1990(E),C89等简单的说,第一个ANSI C标准.

标准说什么这么奇怪?

臭名昭着地说,只需要处理一个符合C的编译器,我引用:

5.2.4.1翻译限制

  • 外部标识符中有6个重要的初始字符

现在,很明显这是非常短暂的,特别是考虑到C没有任何类似于名称空间的东西.在处理外部标识符时,允许描述性名称,了解它们将如何"污染"您链接的所有内容尤为重要.

即使有一个较长的名称标准库任务功能longjmp,tmpfile,strncat.后者,strncat表明他们必须努力发明最初六个字符独特的库名称,而不是可能strcatn与之相冲突的逻辑strcat.

为什么它对我来说仍然是一个问题?

我喜欢旧电脑.我正在尝试编写可以在C99之前的平台上编译和运行的程序,这些程序有时在我心爱的目标上不存在.也许我也喜欢尝试真正遵循标准.我通过挖掘旧标准,试图追踪某些限制和实施问题的原因,学到了很多关于C99和C11的知识.

因此,即使我知道没有编译器或链接器实际执行或强加此限制,但如果我还想使用易读和非冲突的外部标识符,我仍然不能声称我不能声称编写严格符合代码.

他们为什么要强加这样的东西?

他们在八十年代早期的某个时候开始进行标准化工作,并在1988年或1989年最终确定.即使在七十年代和六十年代,处理更长的标识符也不会有任何问题.

考虑到任何想要符合新标准的编译器都必须进行修改 - 如果只是为了更新文档 - 我不知道ANSI如何放下脚并说出类似于"嘿家伙,它是1989年"的说法是不合理的.已经.你必须处理31个重要的初始字符".对于任何平台,即使是古老的平台,它也不会成为问题.

向后兼容?

从我在搜索时读到的内容来看,问题可能来自FORTRAN.在回答问题时,"重要人物"在C(变量)中的确切作用是什么?,Jonathan Leffler写道:

部分麻烦可能是Fortran; 它只需要支持6个字符的单体酶名称,因此在Fortran被广泛使用的系统上的连接器不需要支持更长的名称.

对我来说,这似乎是直接问题为什么最合理的答案.但考虑到每次我想编写一个理论上可以在旧系统上构建的程序时,这种限制都会让我感到困惑,我想知道更多细节.


问题

  1. 在对FORTRAN赛道进行了一些搜索之后,我只想出了理论和挥手.其流行的平台没有实际征收只有6个字符的限制?是否有一个更受欢迎的链接器,迫使标准委员会让步?
  2. 在讨论这些细节时,我还不够大,对这些细节感兴趣.该限制及其理由是否已公开讨论和辩护?是否存在公众哗然,或者只是默默地忽略了?ANSI总部以外的干草叉?

最终,这些问题的答案将使我更容易决定我晚上睡觉时应该为我的职能提供合理的名字.

standards linker c89

9
推荐指数
1
解决办法
1069
查看次数

可以`unsigned int x; scanf("%u",&x);` 真的会导致未定义的行为吗?

有一次我认为我发现了sscanf() 的一个很好的用途,但在阅读了它如何处理整数之后,它似乎不是。有一个应该看起来像这样的字符串:123,456,678我想我可以使用以下代码安全简洁地解析它:

unsigned int x[3];
if( sscanf( s, "%u,%u,%u", x+0, x+1, x+2 ) == 3 )
    …
Run Code Online (Sandbox Code Playgroud)

如果转换失败,我对知道原因并不真正感兴趣,也不担心获得不正确的数据。如果那里有数字以外的东西,scanf()肯定应该创建一个匹配错误并中止,并且它知道我正在寻找一个无符号整数,所以任何负数也应该是一个匹配错误?不。

当我读到转换说明符%u时,我开始怀疑:匹配一个可选的有符号十进制整数。为什么这不是匹配错误?如果签了会怎样?

引自 ISO/IEC 9899:201x 7.21.6.2 ¶ 10,fscanf 函数(重点是我的):

除了 % 说明符的情况外,输入项(或者,在 %n 指令的情况下,输入字符的计数)被转换为适合转换说明符的类型。如果输入项不是匹配序列,则指令执行失败:这种情况是匹配失败。除非赋值抑制由 * 指示,否则转换结果将放置在尚未收到转换结果的格式参数之后的第一个参数所指向的对象中。如果此对象没有合适的类型,或者转换的结果无法在对象中表示,则行为是 undefined

它看起来好像scanf()将每个看起来像整数的转换说明符都视为相同,将输入读取为某种未指定大小的有符号整数,然后绕过所有正常转换写入输出。

例如,根据正常的隐式转换,将任何整数(负数或正数)转换为较小大小的无符号整数表现良好,但不适用于scanf()

unsigned int x;
x = -1;                   /* Well defined: (-1) + (UINT_MAX+1) = UINT_MAX */
sscanf( "-1", "%u", &x ); …
Run Code Online (Sandbox Code Playgroud)

c scanf integer-overflow language-lawyer

5
推荐指数
1
解决办法
130
查看次数

strace 能否告诉我在我的代码中调用了系统调用?

我正在尝试调试为什么ngspice在运行模拟时将烦人的换行符打印到stderr。我试图在可追溯到 1993 年的 2400 个源文件之一中找到它,但这并不像听起来那么容易!然而,这确实意味着我有一个嵌入了所有调试信息的二进制文件。

我的第一个想法是strace可以帮助我找到我认为有问题的调用并将其追溯到源代码。例如,我很确定这是有问题的系统调用:

   brk(0x55d1a84e9000)                     = 0x55d1a84e9000                                                                                                                                         
   clock_gettime(CLOCK_PROCESS_CPUTIME_ID, {tv_sec=0, tv_nsec=61462905}) = 0                                                                                                                        
>> write(2, "\n", 1)                       = 1                                                                                                                                                      
   getrusage(RUSAGE_SELF, {ru_utime={tv_sec=0, tv_usec=26269}, ru_stime={tv_sec=0, tv_usec=35243}, ...}) = 0                                                                                        
   openat(AT_FDCWD, "/proc/self/statm", O_RDONLY) = 3                                   
Run Code Online (Sandbox Code Playgroud)

我曾希望,如果我跟踪一个具有调试信息的可执行文件,strace 会显示源代码中的位置,但这并没有自动发生,而且手册有点压倒性。

我在手册中找到了一个名为Tracing的部分,但找不到任何具体内容。

是否可以使用strace,如果可以:如何?如果没有,您还有其他建议吗?

debugging strace

2
推荐指数
2
解决办法
872
查看次数