小编Pav*_*kin的帖子

是 enum { a } e = 1; 有效的?

一个简单的问题:enum { a } e = 1;有效吗?

换句话说:分配一个不存在于枚举常量值集中的值是否会导致定义明确的行为?

演示:

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ clang t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ icc t0.c -std=c11 -pedantic -Wall -Wextra -c
t0.c(1): warning #188: enumerated type mixed with another type
# note: the same warning for enum { a } e = 0;

$ cl t0.c /std:c11 /Za /c
<nothing>
Run Code Online (Sandbox Code Playgroud)

c enums language-lawyer

25
推荐指数
3
解决办法
1753
查看次数

为什么 GCC 会删除预处理标记之间的空格?

示例代码:

#define X(x,y)  x y
#define STR_(x) #x
#define STR(x)  STR_(x)
STR(X(Y,Y))
Run Code Online (Sandbox Code Playgroud)

调用:

$ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P
"Y Y"

$ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()"
"YY"
Run Code Online (Sandbox Code Playgroud)

为什么 GCC 会删除预处理标记之间的空格?

例如, clang 不会:

$ clang t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()"
"Y Y"
Run Code Online (Sandbox Code Playgroud)

UPD1。,不知何故,gcc 考虑了和之间的空格Y

$ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" -D"Z=STR(X(Y,Y))"
"YY"

$ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P …
Run Code Online (Sandbox Code Playgroud)

c gcc token language-lawyer c-preprocessor

15
推荐指数
1
解决办法
818
查看次数

有哪些非 ISO 实践的例子是 -pedantic 没有发现的?

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

\n
\n

一些用户尝试使用它-Wpedantic来检查程序是否严格符合 ISO C。他们很快发现它并没有达到他们想要的效果:它找到了一些非 ISO 实践,但不是所有\xe2\x80\x94,只有那些 ISO C需要诊断的实践,以及其他一些已添加诊断的实践。

\n
\n

有哪些未发现的非 ISO 实践示例-pedantic

\n

c gcc iso standards-compliance gcc-pedantic

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

如果 x != x 给出相同的结果,为什么 isnan(x) 存在?

众所周知,对于任何浮点类型的变量,x != xiff(当且仅当)xNaN(非数字)。或相反的版本:x == xiffx不是NaN。那么,如果使用语言的自然能力可以获得相同的结果,那么WG14为什么决定定义isnan(x)( math.h) 呢?动机是什么?更好的代码可读性?

额外问题:isnan(x)和之间是否有任何功能差异x != x

c nan ieee-754

8
推荐指数
1
解决办法
225
查看次数

如果 sizeof(int) == sizeof(long),那么 INT_MIN == LONG_MIN &amp;&amp; INT_MAX == LONG_MAX 总是 true 吗?

如果sizeof(int) == sizeof(long),则INT_MIN == LONG_MIN && INT_MAX == LONG_MAX始终为真?

有没有真实存在的案例证明“不真实”?

UPD。类似的问题:是否有 CHAR_BIT > 8 的托管 C 实现?

c integer range sizeof c11

8
推荐指数
1
解决办法
379
查看次数

IEEE 754:带有 fesetround() 的 sqrtf():编译器之间的不同结果:0x42440a72 与 0x42440a73

#include <stdio.h>
#include <stdint.h>
#include <fenv.h>
#include <math.h>

int main()
{
    typedef union { uint32_t u; float f; } ufloat;
    ufloat val;
    float arg = 2401.999999;
    int r;
    r = fesetround(FE_DOWNWARD);
    val.f = sqrtf(arg);
    printf ("FE_DOWNWARD   %22.13a [0x%x] %d\n", val.f, val.u, r);
    r = fesetround(FE_TONEAREST);
    val.f = sqrtf(arg);
    printf ("FE_TONEAREST  %22.13a [0x%x] %d\n", val.f, val.u, r);
    r = fesetround(FE_TOWARDZERO);
    val.f = sqrtf(arg);
    printf ("FE_TOWARDZERO %22.13a [0x%x] %d\n", val.f, val.u, r);
    r = fesetround(FE_UPWARD);
    val.f = sqrtf(arg);
    printf ("FE_UPWARD     %22.13a [0x%x] …
Run Code Online (Sandbox Code Playgroud)

c floating-point rounding ieee-754 cl

7
推荐指数
1
解决办法
100
查看次数

在 Windows / msvc 上 clang:为什么在 FE_UPWARD printf("%.1f\n", 0.0) 下打印 0.1 而不是 0.0?

示例代码(t928.c):

#include <stdio.h>
#include <fenv.h>
#if _MSC_VER && ! __clang__
#pragma fenv_access     (on)
#else
#pragma STDC    FENV_ACCESS ON
#endif

int main(void)
{
        int i = fesetround( FE_UPWARD );
        if ( ! i )
        {
                printf( "%.1f\n", 0.0 );
        }
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用:

$ clang t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1

$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
Run Code Online (Sandbox Code Playgroud)

版本:

$ clang --version
clang version 12.0.0

$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for …
Run Code Online (Sandbox Code Playgroud)

c floating-point rounding clang visual-c++

6
推荐指数
1
解决办法
45
查看次数

将函数指针转换为 uintptr_t / intptr_t 无效吗?

Microsoft 对 C 和 C++ 的扩展

要执行相同的转换并保持 ANSI 兼容性,您可以在将函数指针转换uintptr_t为数据指针之前将其转换为 a:

int ( * pfunc ) ();
int *pdata;
pdata = ( int * ) (uintptr_t) pfunc;
Run Code Online (Sandbox Code Playgroud)

C 的基本原理,修订版 5.10,2003 年 4 月:

即使使用显式强制转换,将函数指针转换为对象指针或 void 指针也是无效的,反之亦然

C11:

7.20.1.4 能够保存对象指针的整数类型

是否意味着pdata = ( int * ) (uintptr_t) pfunc;无效?

正如史蒂夫·萨米特所说

C 标准的编写假设指向不同对象类型的指针,尤其是指向函数而不是对象类型的指针,可能具有不同的表示形式

虽然pdata = ( int * ) pfunc;会导致UB,但似乎会pdata = ( int * ) (uintptr_t) pfunc;导致IB。这是因为“任何指针类型都可以转换为整数类型”和“整数可以转换为任何指针类型”并且uintptr_t …

c type-conversion visual-c++ language-lawyer c11

6
推荐指数
1
解决办法
1244
查看次数

为什么 fseek 有“long int offset”而不是“long long int offset”?

C2x,7.21.9.2 fseek 函数:

概要

#include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);
Run Code Online (Sandbox Code Playgroud)

为什么fseeklong int offset而不是long long int offset

似乎在具有数据模型LLP64 或 ILP32 的操作系统(例如 Microsoft Windows)上2147483647(2 GB)可能不够。

注意:POSIX 的lseekoff_t offset,其中off_t没有非常严格的定义”。

c fseek language-lawyer long-integer c-standard-library

6
推荐指数
1
解决办法
543
查看次数

C2x:alignas 是关键字而不是宏的理由是什么?

1990 年,PJ Plauger 写道(强调是后加的):

然而,标准 C 为您提供了额外的安全级别。据我所知,这是其他语言标准中没有提供的水平。它承诺,如果您避免使用某些名称集,您将不会遇到冲突。因此,标准 C 使得编写高度可移植的应用程序变得更加容易。

在 C11 中,关键字_Alignas(例如)是alignas<stdalign.h>. 这里我们看到关键字是_Alignas, not alignas(因为在 C11 之前的版本中alignas没有保留)。因此,不会与可能的用户定义发生冲突alignas

然而,在 C2x 中, thealignas是一个关键字并且<stdalign.h>不提供任何内容(并且 C2x 没有提及__alignas_is_defined宏——缺陷?)。这意味着在 C2x 中,任何包含用户定义的 C2x 之前的代码都alignas将导致语义违规,从而破坏向后兼容性。

问题:

  1. 这是否意味着自 C2x 以来,“您将不会遇到碰撞”不再成立?
  2. alignas(例如)成为关键字而不是宏的理由是什么?

c backwards-compatibility language-lawyer

6
推荐指数
1
解决办法
155
查看次数