Tag: iso

ISO C和签名的文字常量

我刚刚开始阅读ISO C 2011标准,以及它的最后公开草案[1] ,并意识到在C词汇语法[1] [458ff。]中所有(字面)数字常数都是无符号的。 这是否意味着编译器将带符号的数值常量(如-5.1E10或-1)解释为相应的一元运算符的调用? 例如-1 – (1),+ 512 +(512) 更新:我的错,“所有(文字)数字常数都是无符号的”我的意思是“所有(文字)数值常数都是非负的” 请注意,托马斯

最严格的C代码的GCC选项?

应该设置哪些GCC选项以使GCC尽可能严格? (我的意思是尽可能严格)我在C89写作并希望我的代码符合ANSI / ISO标准。

运营商的C99关联性 – 指定在哪里?

在C99标准中,表达式允许优先级和关联性。 由于运算符在文档中出现的顺序优先级较低,所以优先级记录得非常好,因此函数调用在乘法运算符之前出现,而乘法运算符又在加法运算符之前出现。 但是,我无法找到关联性的明确描述,无论是左还是右。 这很重要,因为(35/5)*2对于一个变体(35/5)*2 35/5*2将是14对于另一个变体35/(5*2) 。 第6.5 Expressions /3, footnote 74节6.5 Expressions /3, footnote 74状态: 语法指定运算符在表达式求值中的优先级,该子表达式与本子条款的主要子条款的顺序相同,优先级最高。 在每个主要子条款中,运算符具有相同的优先级。 左或右相关性在每个子条款中通过其中讨论的表达式的语法指示。 但是,以乘法情况为例,例如: 6.5.5乘法运算符 句法 multiplicative-expression: cast-expression multiplicative-expression * cast-expression multiplicative-expression / cast-expression multiplicative-expression % cast-expression 约束 每个操作数都应具有算术类型。 %运算符的操作数应具有整数类型。 语义 通常的算术转换是在操作数上执行的。 binary *运算符的结果是操作数的乘积。 /运算符的结果是第一个操作数除以第二个操作数的商; %运算符的结果是余数。 在这两个操作中,如果第二个操作数的值为零,则行为未定义。 当整数被划分时, /运算符的结果是代数商,丢弃任何小数部分。 如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a 。 我在那里什么都看不到提到关联性,标准中的其他地方似乎也没有任何默认设置。 我在这里错过了什么吗?

在标准C中声明固定大小的整数typedef

是否有一种可靠的方法来为ISO标准C中的固定8,16,32和64位长度的整数类型声明typedef? 当我说ISO标准C时,我的意思是: ISO C89 / C90,而不是C99。 没有在ISO标准中定义的标头。 没有ISO标准中未定义的预处理器符号。 ISO标准中未指定类型大小的假设。 没有专有供应商符号。 我在StackOverflow中看到了与此类似的其他问题,但没有答案尚未违反上述约束之一。 我不确定没有诉诸平台符号是可能的。

为什么变量不能在C中的2个文件中定义两次

为什么我不能拥有一个; 在2个C文件中。 我打算将两者结合起来制作可执行文件。 我从经验中知道我不能,但我想找到标准C99所说的位置并密封我的理解。 我正在阅读http://www.open-std.org/jtc1/sc22/wg…docs/n1256.pdf中的 ISO C99标准。 它在第42页说: 6.2.2识别者的联系 1可以通过一个称为连接的过程,在不同的范围或相同的范围内多次声明一个标识符。通过一个名为linkage的过程来引用同一个对象或函数。有三种连接:外部,内部和无。 2在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明表示相同的对象或function。 在一个翻译单元内,具有内部链接的标识符的每个声明表示相同的对象或function。 没有链接的标识符的每个声明表示一个唯一的实体。 3如果对象或函数的文件范围标识声明包含存储类指定静态,则标识符具有内部链接。 4对于在存储类规范外部声明的标识符,在该范围内可以看到该标识符的先前声明,如果先前声明指定内部或外部链接,则后面声明中标识符的链接与在先前声明中指定的联系。 如果没有先前的声明可见,或者如果先前的声明没有指定链接,则标识符具有外部链接。 5如果函数的标识符声明没有存储类指定符,则其链接的确定就像是使用存储类指定符extern声明的。如果对象的标识符声明具有文件范围且没有存储空间 – 特定的,它的联系是外在的。 看完之后看起来如果我声明一个变量就像说int a; 在2个源文件中。 然后根据规则5和4都有外部链接,然后根据规则2,两者都应该引用同一个对象。 那为什么编译器会产生问题。 在标准中,暗示我们不能在2个源文件中声明这样,这应该抛出编译错误。 首先,在标准中,它表示int a是一个定义,然后它表示2个定义实例是不可接受的。 我知道这是不允许的,但是如果我能在标准中找到并密封我的理解,这对我来说非常有用。 请将以下标准的摘录与此规则相结合? 或者我错过了胶水? : 声明规定了一组标识符的解释和属性。 标识符的定义是对该标识符的声明: – 对于一个对象,导致为该对象保留存储; – 用于function,包括function体; – 对于枚举常量或typedef名称,是标识符的(唯一)声明。 正如5.1.1.1中所讨论的,预处理后的程序文本单元是一个翻译单元,它由一系列外部声明组成。 这些被描述为“外部”,因为它们出现在任何function之外(因此具有文件范围)。 正如6.7中所讨论的那样,一个声明也会导致为对象或由标识符命名的函数保留存储,这是一个定义。 外部定义是外部声明,它也是函数(除了内联定义)或对象的定义。 如果在表达式中使用了使用外部链接声明的标识符(除了作为sizeof运算符的操作数的一部分,其结果是整数常量),整个程序中的某个地方应该只有一个外部定义用于标识符; 否则,不得超过一个。 谢谢。

C11的__STDC_VERSION__值是多少?

我知道编译器使用__STDC__来表示编译器是标准C,并且从那里,您可以使用__STDC_VERSION__来确定您正在使用的标准级别 。 我也知道C90没有价值,C90修正案1有199401L而C99有199901L 。 最新的C1x草案我简单地说它是201ymmL ,我假设它在最终标准中的价值不那么“模糊”。 我的猜测是,自从C11被批准以来,它将是201112L ,但我想确定一下。 我以为我可以尝试使用gcc -std=c1x但我正在运行的gcc版本还不支持。 有谁知道实际价值是多少?

用scanf检测积分溢出

在最近回答另一个问题时 ,我发现代码有问题,例如: int n; scanf (“%d”, &n); 使用strtol ,您可以检测溢出,因为在这种情况下,允许的最大值被插入到n并且errno被设置为指示溢出,根据C11 7.22.1.4 The strtol, strtoll, strtoul, and strtoull functions /8 : 如果正确的值超出可表示值的范围,则返回LONG_MIN,LONG_MAX,LLONG_MIN,LLONG_MAX,ULONG_MAX或ULLONG_MAX(根据值的返回类型和符号,如果有),并且宏ERANGE的值为存储在errno中。 但是,在标准处理scanf ,特别是C11 7.21.6.2 The fscanf function /10 ,我们看到: 如果此对象没有适当的类型,或者无法在对象中表示转换结果,则行为未定义。 现在,对我而言,这意味着可以返回任何值,并且没有提到errno被设置为任何东西。 这一点已经曝光,因为上面链接问题的提问者将9,999,999,999输入到32位int并返回1,410,065,407 ,值2 33太小,表明它只是在类型的极限处缠绕。 当我尝试它时,我得到了2,147,483,647 ,这是最大可能的32位无符号值。 所以我的问题如下。 在使用scanf系列函数时,如何以便携方式检测积分溢出? 它甚至可能吗? 现在我应该提一下,在我的系统(Debian 7)中,在这些情况下, errno实际上设置为ERANGE但我在标准中找不到任何要求。 此外, scanf的返回值为1 ,表示扫描项目成功。

签名类型的按位移位运算符

我试图理解有符号运算符在有符号和无符号类型上的行为。 根据ISO / IEC文件,以下是我的理解。 左移算子 E1 << E2的结果是E1左移E2位位置 左移帐户中的空位将由零填充。 E1为有符号非负数: E1 << E2将导致E1乘以E2的2次幂,如果该值可由结果类型表示。 Q1:签署否定书怎么样? Q2:我无法理解以下语境中“减少模数”的含义。 “如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数” 。 右移算子 E1 >> E2的结果是E1右移E2位的位置。 E1为有符号非负/无符号 :结果的值是E1 / 2E2的商的整数部分 Q3:对于有符号的负整数,我看到,有些书定义了空位将填充1详细说明使用右移运算符对带符号的负int。

警告:此十进制常量仅在ISO C90中无符号

一段代码: long rangeVar = 0; rangeVar = atol(p_value); if (rangeVar >= -2147483648 && rangeVar <= 2147483647) 在编译时,我得到: 警告:此十进制常量仅在ISO C90中无符号 提前致谢