Tag: 标准

阅读未初始化的内存空间总是不明智吗?

我正在重新创建整个标准C库,我正在为strle n实现一个我希望成为所有其他str函数的基础。 我目前的实施如下: int ft_strlen(char const *str) { int length; length = 0; while(str[length] != ‘\0’ || str[length + 1] == ‘\0’) length++; return length; } 我的问题是,当我通过一个str : char str[6] = “hi!”; 正如所料,内存读取: [‘h’][‘i’][‘!’][‘\0’][‘\0’][‘\0’][‘\0′] 如果你看看我的实现,你可以期望我得到6的回报 – 而不是3(我以前的方法),这样我就可以检查strlen可能包括额外分配的内存。 这里的问题是,我将不得不在初始化内存之外读取1个字节,以便在最后的null终结符处失败我的最后一个循环条件 – 这是我想要的行为。 然而,这通常被认为是不好的做法,并且有些是自动错误。 即使您非常具体地想要读入垃圾值(以确保它不包含’\ 0’),在初始化值之外读取也是一个坏主意吗? 如果是这样,为什么? 我明白那个: “buffer overruns are a favorite avenue for attacking secure programs” […]

该标准是否要求EOF为负数?

是否在标准中写明EOF必须是否定的? 相反, WEOF不需要是否定的。 为什么? wchar_t的情况不能与普通的char任何不同(除了从char到int自动升级扮演角色的情况),因为将wchar_t定义为char对于标准是完全正常的。 因此,必须适用类似的规则。 来自glibc引用的一些引用: 如果将wchar_t定义为char则由于参数提升,必须将类型wint_t定义为int 。 将wchar_t定义为char是合理的

为什么编译器允许字符串文字不是const?

内存中的文字究竟在哪里? (见下面的例子) 我不能修改文字,所以它应该是一个const char *,虽然编译器允许我使用char *,即使有大多数编译器标志也没有警告。 虽然const char *类型的隐式转换为char *类型给了我一个警告,见下文(在GCC上测试,但它在VC ++ 2010上表现相似)。 另外,如果我修改一个const char的值(下面有一个技巧,GCC会更好地给我一个警告),它没有给出错误,我甚至可以在GCC上修改并显示它(即使我猜它仍然是未定义的行为,我想知道为什么它没有对文字做同样的事情)。 这就是为什么我要问那些文字存储在哪里,以及哪些更常见的const应该存储? const char* a = “test”; char* b = a; /* warning: initialization discards qualifiers from pointer target type (on gcc), error on VC++2k10 */ char *c = “test”; // no compile errors c[0] = ‘p’; /* bus error when execution […]

可以将wchar_t提升为wint_t吗?

我看到glibc参考和修订1到C90的一个矛盾。 来自glibc引用的引用说wchar_t可能会被提升为wint_t: 如果将wchar_t定义为char,则由于参数提升,必须将类型wint_t定义为int 但AMD1说: 目前,现有的实现可能有wchar_t为int,wint_t为long,默认促销不会将int更改为long。 基本上,这是由于wchar_t和wint_t是typedef。 因此,我们现在不会将wchar_t提升为wint_t。 有人知道哪一个是正确的吗? 标准是否保证在以下两个程序中转换为unsigned int和int是正确的? (我只是将wint_t和wchar_t替换为它们在glibc中的实际含义)(我只是将wint_t和wchar_t替换为它们在glibc中的实际含义) #include #include int main(void) { setlocale(LC_CTYPE, “en_US.UTF-8”); unsigned int wc; wc = getwchar(); putwchar((int) wc); } – #include #include #include int main(void) { setlocale(LC_CTYPE, “en_US.UTF-8”); int wc; wc = L’ÿ’; if (iswlower((unsigned int) wc)) return 0; return 1; }

安全地添加整数,并certificate安全性

编程课程作业要求 写一个(安全)函数,添加两个整数,和 表明该function是安全的。 以下代码代表我的解决方案。 我不是C标准(或正式validation方法)的专家。 所以我想问:有更好(或不同)的解决方案吗? 谢谢 #include /* Try to add integers op1 and op2. Return 0 (success) or 1 (overflow prevented). In case of success, write the sum to res. */ int safe_int_add(int * res, int op1, int op2) { if (op2 op2 */ /* 0 < – op2 */ /* INT_MIN < […]

声明具有存储类说明符但没有类型说明符的变量是什么意思?

阅读ANSI C Yacc语法规范后,我注意到以下内容都是有效的: register x; auto y; static z; extern q; 这对我来说似乎很奇怪,因为我对类型的理解表明这些变量都没有类型。 这些是什么意思? 他们如何打字? 分配了多少内存?

浮点exception – gcc bug?

请考虑以下代码: #include #include int main() { #pragma STDC FENV_ACCESS ON 1.0/0.0; printf(“%x\n”, fetestexcept(FE_ALL_EXCEPT)); } 我希望它打印一个对应于FE_DIVBYZERO的非零值,但它会打印0.将main的第二行更改为double x = 1.0/0.0; 给出了预期的行为。 这是允许的,还是一个bug? 编辑:对于它的价值,起初似乎在大多数现实世界的代码中,可能导致引发fenvexception的操作无法优化,因此可以安全地执行大型计算并在最后检查是否有溢出,div-by-zero等发生了。 但是,当您考虑内联和优化时,事情会变得混乱,并且会出现真正的问题。 如果这样的函数在由于常量参数总是最终除以零的情况下被内联,那么gcc可能会变得非常聪明并优化整个内联函数,主要是为了return INFINITY; 没有提出任何例外。

和的等价性

这保证总是如此: std::numeric_limits::max() == INT_MAX C ++标准对此有何评论? 我在标准中找不到任何明确说明这一点的参考,但我继续读到那些应该是等价的。 对于同时实现C99(至少long long部分)和C ++ 98的编译器,C99类型不是C ++ 98标准呢? 我不确定是否有任何保证这一点始终成立: std::numeric_limits::max() == ULLONG_MAX 这是一个合理的假设吗?

如何在C中应用最后一个整数提升规则?

6.3.1.8p1:否则,将对两个操作数执行整数提升。 然后将以下规则应用于提升的操作数:如果两个操作数具有相同的类型,则不需要进一步转换。 否则,如果两个操作数都具有有符号整数类型或两者都具有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数的类型。 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数类型的操作数的类型。 否则,两个操作数都转换为无符号整数类型,对应于带有符号整数类型的操作数的类型。 对于要应用的粗体规则,它似乎暗示您需要具有无符号整数类型,其等级小于有符号整数类型, 并且有符号整数类型不能保存无符号整数类型的所有值。 是否存在这种情况的现实世界的例子,或者这个声明是否涵盖所有可能的排列?

C预处理器语句是否是C语言的一部分?

我记得我的一位教授在C课程中的主张。 他说,# #define预处理器命令使程序员能够创建一个常量,以便在以后的代码中使用,并且该命令是C语言的一部分 。 /* Is this truly C code? */ #define FOO 42 由于这是一个介绍性的编程类,我怀疑他只是简化了源文件和编译器之间的关系,但我希望validation我的理解。 预处理器语句是否完全独立于C语言(取决于所使用的特定编译器)还是在C99标准中明确描述? 出于好奇,K&R曾经提到过预处理器宏吗?