标签: c99

从具有灵活数组成员的结构转换为不具有灵活数组成员的结构是否是未定义的行为?

我想要一个可变大小的结构,但我想将具有特定大小的结构实例嵌入到另一个结构中。想法是这样的:

struct grid {
    size_t width, height;
    int items[ /* width * height */ ];
};

struct grid_1x1 {
    size_t width, height;
    int items[1];
};

struct grid_holder {
    struct grid_1x1 a, b;
};

int main(void)
{
    struct grid_holder h = {
        .a = { .width = 1, .height = 1, .items = { 0 } },
        .b = { .width = 1, .height = 1, .items = { 0 } },
    };
    struct grid *a = (struct grid *)&h.a, *b …
Run Code Online (Sandbox Code Playgroud)

c struct c99

3
推荐指数
1
解决办法
298
查看次数

#if 指令中的求值顺序:宏扩展与“define”关键字

当 c 预处理器运行#if/#elif预处理指令时,它会对直接跟随的标记执行 4 个操作:

  1. 如果已定义,则将每次出现的 替换defined {identifier}为其他情况。1{identifier}0
  2. 调用所有宏。
  3. 将所有剩余的标识符替换为0
  4. 将结果解析并评估为constant-expression.

现在,从标准(c99,6.10.1)中可以很清楚地看出,步骤 3 和 4 实际上按该顺序发生,并且在步骤 1 和 2 完成之后。但我找不到关于1和2顺序的任何说明。

从我所做的一些有限测试来看,gcc 似乎根据标记的顺序执行步骤 1 和 2 - 在 中defined MACROdefined首先执行,但在MACRO(defined ID)宏中执行。

标准是否要求这种行为?实现定义的?不明确的?

c standards c99 language-lawyer c-preprocessor

3
推荐指数
1
解决办法
126
查看次数

使用复合文字对静态数组进行条件初始化

#include <stdint.h>\n\n#define INIT_UINT32 1\n#define INIT_INT32  2\n\n#define INIT INIT_INT32\n\ntypedef union\n{\n  uint32_t a;\n  int32_t  b;\n} Foo_t;\n\n/* Why does this compile... */\nstatic Foo_t foo_static = INIT == INIT_INT32 ?\n    (Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX };\n\n/* but this doesn't? */\nstatic Foo_t foo_static_array[] =\n{\n  INIT == INIT_INT32 ? (Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX }\n};\n\nint main(void)\n{\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译时,使用复合文字的 foo_static 条件初始化成功,但使用复合文字的 foo_static_array 条件初始化失败。以下是编译错误。

\n
$ gcc test.c\ntest.c:4:21: error: initializer element is not constant\n    4 | #define INIT_INT32  2\n      | …
Run Code Online (Sandbox Code Playgroud)

c c99

3
推荐指数
1
解决办法
87
查看次数

void * 和 char * 之间的兼容性

void 和 char 指针是否保证具有相同的内存表示形式?

换句话说,执行以下命令后:

char a = 'z';
void *b = &a;
char *c;

memcpy(&c, &b, sizeof(b));
Run Code Online (Sandbox Code Playgroud)

我可以确定*c == 'z'(没有未定义的行为等)吗?

c c99 void-pointers language-lawyer

3
推荐指数
1
解决办法
133
查看次数

C 语言中 CORDIC 对数的问题

为了开始使用 CORDIC for ,我实现了此 PDF 第 6 页log10中派生的算法:

\n
#include <stdio.h>\n#include <math.h>\n\n// https://www.mikrocontroller.net/attachment/31117/cordic1.pdf\nfloat logf_cordic (float x, int B)\n{\n    float z = 0.0f;\n\n    for (int i = 1; i <= B; i++)\n    {\n        if (x > 1.0f)\n        {\n            printf ("-");\n            x = x - ldexpf (x, -i);\n            z = z - log10f (1.0f - ldexpf (1.0f, -i));\n        }\n        else\n        {\n            printf ("+");\n            x = x + ldexpf (x, -i);\n            z = z - log10f (1.0f + ldexpf (1.0f, …
Run Code Online (Sandbox Code Playgroud)

c c99 numerical-methods

3
推荐指数
2
解决办法
244
查看次数

GCC 关于将其作为 VLA 的说法正确吗?

这个问题与“ Are conformant arrayparameters VLAs? ”非常相似,唯一的区别是这里我在数组声明的andstatic中使用关键字(C99 中引入),这意味着声明的数组应该有空间至少对于元素。这是一个例子:[]len

\n
#include <stddef.h>\n#include <stdio.h>\n\nvoid print_array(size_t len, const int arr[static len]) {\n    for (size_t i = 0; i < len; i++) {\n        printf("%d\\n", arr[i]);\n    }\n}\n\nint main(void) {\n    const int arr[] = {1, 2, 3, 4};\n    print_array(sizeof arr / sizeof *arr, arr);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当在 GCC 和 Clang 上使用该-Wvla标志编译此代码时,会发出以下警告:

\n
main.c:4:1: warning: ISO C90 forbids variable length array \xe2\x80\x98arr\xe2\x80\x99 [-Wvla]\n    4 | void print_array(size_t len, const int …
Run Code Online (Sandbox Code Playgroud)

c c99 language-lawyer

3
推荐指数
1
解决办法
134
查看次数

当参数数量多于格式中指定的参数时,vsprintf() 不会打印警告

我尝试使用简单的日志记录机制在创建日志时创建错误检查。我观察到,与 printf 相比,可以使用vfprintf(),它在编译时不会打印任何警告,传递给 format 的参数太多(参见下面的示例)。(我不希望他们有相同的行为,但我仍然期望类似的行为)。关于这个问题,即使在编译时已知可变参数的数量。在编译时是否可以通过任何方式进行检查?\n下面,我准备了一个代码示例,在编译时编译器将打印有关 printf 的警告,并且工作vfprintf()正常,没有任何错误。也许第二个可变参数被忽略了?我读过这个人,但找不到任何有用的信息。

\n
#include <stdarg.h>\n#include <stdio.h>\n\nvoid check_printf_usage(char *fmt, ...)\n{\n    va_list ap;\n    \n    va_start(ap, fmt);\n    vfprintf(stdout, fmt, ap);\n    va_end(ap);\n}\n\nint main()\n{\n    int x = 1;\n    int y = 2;\n    printf("test nr.1 %i\\n", x, y); // works as expected, prints warning\n    check_printf_usage("test nr.2 %i\\n", x, y); // does not print any warning\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是编译输出+程序输出:

\n
#include <stdarg.h>\n#include <stdio.h>\n\nvoid check_printf_usage(char *fmt, ...)\n{\n    va_list ap;\n    \n    va_start(ap, fmt);\n    vfprintf(stdout, fmt, ap);\n    va_end(ap);\n}\n\nint main()\n{\n    int …
Run Code Online (Sandbox Code Playgroud)

c printf c99 variadic variadic-functions

3
推荐指数
1
解决办法
63
查看次数

为什么Visual Studio C编译器不是这样的?

以下代码使用gcc -std = c99在Linux上编译正常但在Visual Studio 2010 C编译器上获得以下错误:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

fib.c
fib.c(42) : error C2057: expected constant expression
fib.c(42) : error C2466: cannot allocate an array of constant size 0
fib.c(42) : error C2133: 'num' : unknown size

用户输入要生成的斐波那契数量.我很好奇微软编译器为什么不喜欢这段代码.

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

void fib(int max);

int main(int argc, char *argv[])
{    
    int argument;

    if (argc != 2)
    {
        puts("You must supply exactly one …
Run Code Online (Sandbox Code Playgroud)

c compiler-construction c99 visual-studio

2
推荐指数
1
解决办法
1119
查看次数

使用C99标准会导致GCC编译器错误

我有一个非常简单的打印程序叫做"print.c":

#include <stdio.h>

int main(void){
        printf("Random words");
}
Run Code Online (Sandbox Code Playgroud)

使用该命令进行编译gcc -o print print.c会导致完全干净的编译,并且可执行文件按预期运行.

用命令编译gcc -o -std=c99 print print.c给我:

print: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crti.o:(.fini+0x0): first defined here
print: In function `__data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o:(.data+0x0): first defined here
print: In function `__data_start':
(.data+0x4): multiple definition of `__dso_handle'
/usr/lib/gcc/i686-linux-gnu/4.6.1/crtbegin.o:(.data+0x0): first defined here
print:(.rodata+0x4): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
print: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o:(.text+0x0): first …
Run Code Online (Sandbox Code Playgroud)

c gcc c99

2
推荐指数
1
解决办法
2707
查看次数

GCC:允许在C99中重载功能

我在C99中编写代码并通过GCC编译.我想使用函数重载的风格原因(否则我必须自己做名称修改).

我读过有没有理由说C99不支持函数重载?但是,我仍然想知道它是否可以在GCC中启用.

你能帮助我吗?

c gcc overloading c99

2
推荐指数
1
解决办法
4512
查看次数