用 C 编程:预期常量表达式错误

Programming in C: Expected constant expression error

我目前正在尝试编译从 github 获取的 crc 计算器,但在 visual studio 2015 年编译时遇到困难。我收到以下行的错误预期常量表达式:

char paths[strlen(src) + 1 + strlen(name) + 2 + 1];

关于如何解决错误的想法?

static int create_source(char *src, char *name, FILE **head, FILE **code) {
    // for error return
    *head = NULL;
    *code = NULL;

    // create the src directory if it does not exist
    int ret = _mkdir(src, 0755);
    if (ret && errno != EEXIST)
        return 1;

    // construct the path for the source files, leaving suff pointing to the
    // position for the 'h' or 'c'.
    char paths[strlen(src) + 1 + strlen(name) + 2 + 1];
    char *suff = stpcpy(path, src);
    *suff++ = '/';
    suff = stpcpy(suff, name);
    *suff++ = '.';
    suff[1] = 0;

    // create header file
    *suff = 'h';
    *head = fopen(path, "wx");
    if (*head == NULL)
        return errno == EEXIST ? 2 : 1;

    // create code file
    *suff = 'c';
    *code = fopen(path, "wx");
    if (*code == NULL) {
        int err = errno;
        fclose(*head);
        *head = NULL;
        *suff = 'h';
        unlink(path);
        return err == EEXIST ? 2 : 1;
    }

    // all good -- return handles for header and code
    return 0;
}

您的直接问题是您正在尝试使用 VLA(可变长度数组),它在 C99 标准中被引入,但编译器不支持 VLA。在没有 VLA 支持的情况下,必须使用 整数常量 声明数组(而不仅仅是 const int)。从 C11 开始,对 VLA 的支持是可选的。

要解决您眼前的问题并提供可移植性,只需为 paths 而不是 malloc 分配存储空间。 free 你之前的记忆 return 来自你的函数(无论是错误 return 还是成功)

您可以这样做:

size_t pathlen = strlen(src) + 1 + strlen(name) + 2 + 1;
char *paths = malloc (pathlen);     /* allocate storage for paths */
if (!paths) {                       /* validate EVERY allocation */
    perror ("malloc-paths");
    return 3;   /* or however you want to handle the error */ 
}
char *suff = stpcpy(path, src);

...

*head = fopen(path, "wx");
if (*head == NULL) {
    free (path);                    /* free paths */
    return errno == EEXIST ? 2 : 1;
}

...

if (*code == NULL) {
    int err = errno;
    free (path);                    /* free paths */
    fclose(*head);
    *head = NULL;
    *suff = 'h';
    unlink(path);
    return err == EEXIST ? 2 : 1;
}

free (path);                        /* free paths */
return 0;

allocation 和 free 的开销很小,但在你的情况下可以忽略不计,因为只有一个 allocation 和一个 free。

作为 David 解决方案的简单替代方案,您还可以使用 FILENAME_MAX ...

[...] which expands to an integer constant expression that is the size needed for an array of char large enough to hold the longest file name string that the implementation guarantees can be opened; (§7.21.1, ISO C11)

像这样

char paths[FILENAME_MAX];

不过,您可能想检查一下是否超出了这个大小。