我有一个关于部分问题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被广泛使用的系统上的连接器不需要支持更长的名称.
对我来说,这似乎是直接问题为什么最合理的答案?.但考虑到每次我想编写一个理论上可以在旧系统上构建的程序时,这种限制都会让我感到困惑,我想知道更多细节.
最终,这些问题的答案将使我更容易决定我晚上睡觉时应该为我的职能提供合理的名字.
有一次我认为我发现了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) 我正在尝试调试为什么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,如果可以:如何?如果没有,您还有其他建议吗?