簡體   English   中英

頭文件中的C typedef在文件范圍內可變地修改

[英]C typedef in header file variably modified at file scope

我需要在兩個源文件中包括一些typedef定義:

typedef double mat[MATSIZE][MATSIZE] ;

所以我創建了def.h,其中包括:

#ifndef DEF_H
#define DEF_H
typedef double mat[MATSIZE][MATSIZE] ;
#endif

在兩個.c文件中,我通過以下方式將其包括在內:

在處理的第一個文件中:

#define MATSIZE 4
#include "def.h"

在第二個.c文件中:

extern int MATSIZE;
#include "def.h"

但是我明白了

error: variably modified ‘mat’ at file scope

我做錯了什么?

可變長度數組(VLA)的概念對於C99是“新的”。

在C99之前,您只能使用實常數來指定數組的大小。 以下代碼在塊范圍或文件范圍內都是非法的。

const int size = 42; /* size is not a real constant */
int boo[size];

C99引入了VLA 用於塊范圍 上面的示例代碼是合法的C99,只要它發生在塊范圍內即可。 您的定義在文件范圍內,因此無效。


同樣的typedef引用兩個不同的類型也是一個非常糟糕的主意。

當在塊外部(在文件范圍或全局范圍)定義數組時,必須在編譯時知道大小。 這意味着數組上的每個維數必須是一個恆定的整數值(或者,對於第一個維數,數組的初始化程序可能會暗示它)。

如果使用C89編譯器,則可能會收到有關非恆定數組尺寸的消息。 GCC 4.6.1給出了“文件范圍內的可變修改mat ”消息。

C99在庫中添加了“可變長度數組”,但它們只能出現在塊或參數列表中,在此可以在運行時確定大小。

因此,在一個函數中,您可以合法地編寫:

extern int MATSIZE;

extern void func(void);

void func(void)
{
    typedef double mat[MATSIZE][MATSIZE];
    // ...
}

(需要使用函數聲明來避免出現以下警告:

warning: no previous prototype for ‘func’ [-Wmissing-prototypes]

因為我習慣使用-Wmissing-prototypes編譯。)

另一個問題是,在一個文件中, MATSIZE是一個編譯時( #define d)常量; 另一方面,顯然有一個整數變量MATSIZE 這些是完全無關的。 因此,類型是不同的。


typdef是塊作用域的

wildplasser關心typedef是塊作用域還是全局作用域。 它是塊作用域的,如下面的可執行代碼所示:

#include <stdio.h>

static void function(void)
{
    typedef int i;
    i j = 1;
    printf("j = %d\n", j);
    {
    typedef double i;
    i j = 2.1;
    printf("j = %f\n", j);
    }
    {
    typedef char i[12];
    i j = "this works";
    printf("j = %s\n", j);
    }
}

int main(void)
{
    function();
    return(0);
}

如果提供給我進行代碼審查,則該摘要將被拒絕。 但是,它充分說明了這一點。

MATSIZE未知。 這就是為什么您遇到此問題。

#ifndef DEF_H
#define DEF_H

#define MATSIZE 100 /* or whatever */

typedef double mat[MATSIZE][MATSIZE]

#endif 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM