簡體   English   中英

錯誤初始化元素不是常量

[英]Error initializer element is not constant

我的代碼有問題,我無法解決....

報告錯誤的代碼段:

static FILE *debugOut = stderr;
static FILE *infoOut = stdout;

gcc返回的錯誤是:

initializer element is not constant

嘗試在主要做例如:

static FILE *debugOut;
static FILE *infoOut;

main(){
    debugOut = stderr;
    infoOut = stdout;


}

ANSI C標准不要求stderr / stdout必須是常量表達式。

因此,取決於使用的標准C庫代碼

static FILE *debugOut = stderr;

編譯或產生您詢問的錯誤消息。

例如, GNU C庫將 stderr / stdout / stdin 定義為非常量表達式。

您基本上有兩種選擇來處理這種情況,即使這些代碼可移植。

從main初始化

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

int main(int argc, char **argv)
{
  debugOut = stderr;
  infoOut  = stdout;
  // [..] 
  return 0;
}

從構造函數初始化

在許多平台上,您可以將函數聲明為構造函數,這意味着它在調用main()之前在啟動時調用。 例如,當使用GCC時,您可以像這樣實現它:

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

static void init_streams(void) __attribute__((constructor)); 
static void init_streams(void)
{
  debugOut = stderr;
  infoOut  = stdout;
}

這種構造函數屬性語法不是標准化的,但由於GCC非常普遍,而其他編譯器都在努力實現GCC兼容性,因此實際上它非常便於攜帶。

如果您需要將其移植到沒有類似聲明功能的其他編譯器,您可以使用__GNU_LIBRARY__和/或__GNUC__等宏來保護此代碼。

從C99標准:

6.7.8初始化

約束

4具有靜態存儲持續時間的對象的初始值設定項中的所有表達式應為常量表達式或字符串文字。

因此,

static FILE *debugOut = stderr;
static FILE *infoOut = stdout;

如果編譯器認為stderrstdout不是常量表達式,則不是合法代碼。

這是標准對stderrstdout看法。

7.19輸入/輸出<stdio.h>

7.19.1簡介

...

  stderr stdin stdout 

它是“指向FILE的指針”類型的表達式,它們分別指向與標准錯誤,輸入和輸出流相關聯的FILE對象。

處理此問題的標准兼容方法是將變量初始化為NULL並在main設置它們的值。

static FILE *debugOut = NULL;
static FILE *infoOut  = NULL;

int main()
{
  debugOut = stderr;
  infoOut  = stdout;

  ...

暫無
暫無

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

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