【问题标题】:C Storage Size Isn't a Constant...why?C 存储大小不是一个常数...为什么?
【发布时间】:2013-09-01 21:04:50
【问题描述】:

这是一个简单的示例程序

#include <stdio.h>
#include <string.h>

const char *hello_string = "Hello";

int main(void)
{
char *world_string = " World";
static char hello_world[strlen(hello_string)+strlen(world_string)];
strcpy(&hello_world[0], hello_string);
strcat(&hello_world[0], world_string);
printf("%s\n", hello_world);
return 0;
}

编译器输出:

test.c: In function ‘main’:
test.c:9:13: error: storage size of ‘hello_world’ isn’t constant
static char hello_world[strlen(hello_string)+strlen(world_string)];
            ^

我意识到在这种情况下完全无用和不必要的使用“静态”会导致错误,并且删除它后编译会正常。这只是一个简单的例子来说明我的问题。

我不明白为什么当“hello_string”被声明为 const char * 并且它的大小在执行过程中不会改变时,存储大小不是一个常数。这只是编译器不够聪明的一个例子吗?

【问题讨论】:

  • 重复,见答案here

标签: c size storage constants


【解决方案1】:

当编译器抱怨存储大小不是常量时,这意味着编译时常量,即编译器可以在编译时确定的值。 strlen 的调用显然会在运行时发生,因此编译器无法知道数组的大小。

试试这个:

#include <stdio.h>
#include <string.h>

const char hello_string[] = "Hello";

int main(void)
{
    char world_string[] = " World";
    static char hello_world[sizeof hello_string + sizeof world_string];
    strcpy(&hello_world[0], hello_string);
    strcat(&hello_world[0], world_string);
    printf("%s\n", hello_world);
    return 0;
}

【讨论】:

    【解决方案2】:

    strlen 是一个函数。它的返回值不能在编译时计算。

    【讨论】:

    • 为什么不能在编译时计算strlen("Hello")的值?它当然可以,而且像gcc 这样的编译器甚至会实际进行这种优化。问题是 C 在这里需要一个整数常量表达式,并且使用函数调用使表达式不符合 C 规则被视为常量的条件。
    • @ouah 因为strlen 是一个函数。根据链接目标文件的方式,不能保证它是一个实际计算字符串长度的函数。不允许编译器推断。
    • 那为什么这段代码有同样的错误呢? static const uint16_t width = 480;static uint16_t tdl[width]={0};
    【解决方案3】:

    您在数组声明中使用了static 存储类指定符。

    static 数组只能有固定长度:即数组的大小必须是整数常量表达式。涉及函数调用的表达式不是常量表达式。

    如果要使用可变长度数组,请删除 static 说明符。然后不要忘记在数组中为空终止符保留一个额外的字符。

    【讨论】:

    • 那为什么这段代码有同样的错误呢? static const uint16_t width = 480;static uint16_t tdl[width]={0};
    【解决方案4】:

    strlen() 是一个函数调用。编译器不知道它做了什么。

    试试sizeof (*hello_string)。我不确定这是否可行。

    或者const char hello_string[] = "Hello"sizeof(hello_string),在我看来这更有可能奏效。

    【讨论】:

    • sizeof *hello_string 将评估为1。另请注意,sizeof 不是函数,因此您无需执行 sizeof(*hello_string)
    猜你喜欢
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2021-04-05
    • 2012-05-13
    • 2017-08-25
    • 1970-01-01
    • 2016-10-25
    • 2012-08-28
    相关资源
    最近更新 更多