Tag: c89

向size_t添加或指定整数文字

在CI中,可以看到许多代码将size_t变量添加或赋予整数文字。 size_t foo = 1; foo += 1; 这里发生了什么转换,是否会发生size_t “升级”为int然后转换回size_t ? 如果我在最大程度上,那还会环绕吗? size_t foo = SIZE_MAX; foo += 1; 这是定义的行为吗? 它是一个无符号类型size_t ,它添加了一个signed int (可能是一个更大的类型?)并转换回size_t 。 有签名整数溢出的风险吗? 写一些像foo + bar + (size_t)1而不是foo + bar + 1这样有意义吗? 我从来没有看到这样的代码,但我想知道如果整数促销是麻烦的话是否有必要。 C89没有说明size_t将如何排名或者究竟是什么排名: 结果的值是实现定义的,其类型(无符号整数类型)是在头中定义的size_t。

合法的数组赋值。 可能吗?

在阅读了关于K&R书中结构的章节之后,我决定做一些测试来更好地理解它们,所以我写了这段代码: #include #include struct test func(char *c); struct test { int i ; int j ; char x[20]; }; main(void) { char c[20]; struct {int i ; int j ; char x[20];} a = {5 , 7 , “someString”} , b; c = func(“Another string”).x; printf(“%s\n” , c); } struct test func(char *c) { struct […]

隐含function声明在C89中是合法的吗?

考虑这个C程序: int main() { puts(“Hello world!”); return 0; } 编译并运行正常,据我所知,是合法的C89。 但是,我不是百分百肯定的。 使用clang在C99模式下编译告诉我在C99中implicit declaration of function ‘puts’ is invalid in C99 (这让我觉得C标准必须在C99中改变以使隐式函数声明非法,这就是我要确认的)。 隐含function声明在C89中是合法的吗? (即使这样做是个坏主意(除非你在混淆的C代码挑战中))

使用gcc在C中键入typesafe varargs

很多时候我想要一个函数来接收可变数量的参数,例如以NULL结尾 #define push(stack_t stack, …) _push(__VARARG__, NULL); func _push(stack_t stack, char *s, …) { va_list args; va_start(args, s); while (s = va_arg(args, char*)) push_single(stack, s); } 如果foo收到非char*变量,我可以指示gcc或clang警告吗? 类似于__attribute__(format) ,但是对于同一指针类型的多个参数。

C的哪些部分最便携?

我最近阅读了Lua共同创作者Luiz H. de Figueredo和Roberto Ierusalimschy的采访,他们在那里讨论了Lua的设计和实现。 至少可以说是非常有趣的。 然而,讨论的一部分在我的脑海中带来了一些东西。 Roberto称Lua是一个“ 独立应用程序 ”(也就是说,它是纯粹的ANSI C,它不使用操作系统。)他说,Lua的核心是完全可移植的,并且因为它的纯度已经能够移植很多更容易和甚至从未考虑过的平台(例如机器人和嵌入式设备)。 现在这让我很奇怪。 C一般来说是一种非常便携的语言。 那么,C的哪些部分(即标准库中的部分)是最不可移植的? 什么是可以预期在大多数平台上工作的? 是否应该只使用一组有限的数据类型(例如避免short和可能float )? FILE和stdio系统怎么样? malloc和free ? 似乎Lua避免了所有这些。 这会把事情发挥到极致吗? 或者它们是可移植性问题的根源? 除此之外,还有什么其他方法可以使代码非常便携? 我问这一切的原因是因为我目前正在用纯C89编写一个应用程序,并且它最好是尽可能便携。 我愿意采取一条中间路来实现它(足够便携,但没有那么多,我必须从头开始编写所有内容。)无论如何,我只是想看看编写最佳C代码的关键。 最后,所有这些讨论仅与C89有关。

我应该使用“-ansi”或显式“-std = …”作为编译器标志吗?

我已经读过 ANSI C与ISO C不完全相同,编译器可能在解释“-ansi”的含义上有所不同。 (gcc将其映射到C90,clang将其映射到C89)目前我倾向于使用“-std = …”而不是“-ansi”,因为它明确地显示了使用哪个标准。 由于我特别感兴趣的是在Linux,Windows和MAC上编译,我担心一些编译器无法理解“-std = …”而是“-ansi”。 那么使用一个在另一个上有任何利弊吗?

超出翻译限制是不确定的行为,是否有检查工具来找到它?

原始问题: 我正在搜索C90标准,以便在编写高可移植代码时注意事项,同时对编译器供应商的良好意愿缺乏信任,并假设我的软件有时可能会杀死某人,如果我做错了。 让我们说我有点偏执。 目前我在考虑“翻译限制”(5.2.4.1 ANSI / ISO 9899:1990)。 正如标准中所指出的那样:“ ansi C是否限制了程序中外部变量的数量? ”,这些是标准符合实现的最低要求。 现在另一方面,这意味着,任何实现都不需要做更多 – 如果我想确保我的代码适用于任何confrom实现,这些限制代表我的绝对限制。 到目前为止很烦人。 因此编译器供应商选择的限制等于或高于最低要求的转换限制。 如果超出特定实施的实施定义的转换限制,现在会发生什么? 在我的ANSI / IO 9899:1990(C90)副本中,我没有找到任何东西,所以我认为它是“3种类型的未定义行为”(通过省略)。 另一方面,这不是第一次,我误解了标准或没有找到合适的通道。 所以这是我的问题: IS是否超过C90中特定实现未定义行为的转换限制? C90行为是否适用于C95 / C96以及新迭代C99和C11的修正版本? 有没有人看过那里的检查工具,检查最小的或(工具)用户定义的限制? 超出原始问题的方面: 答案和评论中有趣的方面: 1)正如迈克尔·伯尔在对该问题的直接评论中指出的那样,根据C标准(我只检查了没有更正的C90,以及C99草案,Michael 在这里引用),符合C的实现只需要接受一个程序,它同时包含所有限制,在最严格的解释中取消任何最小限制保证。 2)正如rubenvb和Keith Thompson指出的那样,某些质量的实现应该为案例提供诊断,超出它们的实现定义限制,特别是如果不符合最低要求(rubenvb在评论中链接了MSVC的示例) 。 3)由于超出编译器限制可能是未定义的行为,但肯定会导致某些错误,转换限制适用于我的某段代码的“变量”的值代表重用的前提条件。 我个人的策略来处理它们 1)因此,对于最大的偏执狂,我会愚弄自己,并惹恼编译器供应商的支持,请求保证我,实现选择的限制适用于任何程序。 🙁 2)因此,我将研究编译器文档以及编译器支持获得确认的痛苦程度: – 对于每个转换限制,如果超出,将引发诊断,并且 – 因为它是未定义的行为,如果每个超出翻译限制的实例都会引发诊断 – 或者另一个错误已经阻止了编译。 3)因此,我将尝试开发一个工具(或者如果我真的必须开发自己),测量这些值,并将它们作为我的程序的代码重用的前提条件。 正如Keith Thompson在本回答中指出的那样,一些价值观可能需要更深入地了解实施如何实施。 我不能完全确定在这种情况下除了2)中的行为之外还能提供什么帮助。但是,据我所知,我必须进行测试 – 但我只需要测试是否有UB(没有诊断),如果这是在这种情况下,成功的测试不能保证一般情况下的正确性。 回答说: 是的,它是未定义的行为。 […]

ANSI C和ISO C之间有什么区别吗?

我知道C有ANSI标准和ISO标准。这两个标准之间有什么区别吗? 如果是这样,他们是什么? 如果没有差异那么有两个标准是什么意思?

哪些C99function被视为有害或不受支持

我通常在C89中编写C代码,现在C99的一些function(如intxx_t或__VA_ARGS__或snprintf )非常有用,甚至可能至关重要。 在我更多地从C89到C99的要求之前,我想知道哪些C99function得到了广泛支持,哪些function得不到广泛支持甚至被认为是有害的。 我知道我们可以检查我们的目标编译器支持,但这会缩小我们的支持范围,因为这是开源软件,我更希望得到更广泛的支持。 例如,我们使用Solaris(suncc)编译器和gcc,但是我们可能会有其他编译器移动,而我们可以通过很少的努力保持兼容性。 例如,我从未在Windows上工作,也不了解Windows编译器,但保持Windows兼容性会很好。

如何在gcc中强制执行C89样式的变量声明?

我在代码库上工作,主要是带有一点点C ++的C语言,并且主要是用gcc构建的,但偶尔需要用MSVC构建。 微软的C编译器仍然是C89,只有一些小的扩展,它仍然不支持C ++ / C99的混合代码和变量定义。 因此,我需要找到一种方法来防止开发人员在使用gcc时编写无序代码/变量定义,否则构建随后会破坏MSVC。 如果我使用gcc -std=c89那么一切都会中断,因为不允许使用C ++风格的注释(可能还有其他问题,但我还没有进一步研究过)。 如果我使用gcc -std=gnu89则允许无序代码/变量定义,这对我也没有帮助。 有任何想法吗 ? 我想我只需要像gcc -std=c99 -fno-inline-variable-definitions这样的选项,如果存在这样的选项的话。