C 11 與 C99的相容

2021-07-10 07:49:21 字數 3145 閱讀 7233

c++對以下c99特性的支援納入了新標準之中:

1、c99中的預定義巨集

2、__func__預定義識別符號

3、_pragma操作符

4、不定引數巨集定義以及__va_args__

5、寬窄字串連線

使用上述巨集可以檢查機器環境對c標準和c庫的支援情況。

#include using namespace std;

int main()

在g++ 2.3.3版本中後面兩行不能編譯通過,說明在g++ 2.3.3版本中可能沒有給出這兩個巨集的定義。

很多現實的編譯器都支援c99標準中的__func__預定義識別符號功能,其基本功能就是返回所在函式的名字。

#include using namespace std;

const char* hello()

const char* world()

int main()

tips:vs2012中不支援,g++ 3.3.2版本支援,這個版本的g++還不支援c++11標準。所以這是相容c99標準。

__func__在按照標準定義,編譯器會隱式地在函式定義後面定義__func__識別符號。

const char* hello()

在c++11標準中,還允許在類和結構體中使用這個巨集。

#include using namespace std;

struct teststruct

const char* name;

};int main()

但是將__func__識別符號作為函式引數的預設值是不允許的。

void funcfail(string func_name = __func__){};  //編譯不能通過

在c/c++標準中,#pragma是一條預處理指令。

#pragma once

上述**和

#ifndef this_header

#define this_header

//一些標頭檔案定義

#endif

c++11中定義乙個_pragma操作符和#pragma作用相同。_pragma操作符的格式如下:

_pragma(字串字面量)

使用_pragma操作符想要達到#pragma once的效果可以:

_pragma("once")

在c99標準中,程式設計師可以使用變長引數的巨集定義。變長引數的巨集定義是指在巨集定義中引數列表的最後乙個引數為省略號,而預定義巨集__va_args__則可以在巨集定義的實現部分替換省略號所代表的字串。

#define pr(...) printf(__va__args__)

就可以定義乙個printf的別名pr。事實上,變長引數巨集和printf是一對好搭檔。

#include #define log(...) ;\

fprintf(stderr,__va__args__);\

fprintf(stderr,"\n");\

}int main()

上述例子在vs2012中不支援,在g++ 3.3.2版本支援

在c++11中,在將窄字串和寬字串進行連線時,支援c++11標準的編譯器會將窄字串轉換成寬字串,然後再與寬字串進行連線。

6、擴充套件的整型

c++11中一共只定義了5種標準的有符號整型:

signed char

short int

intlong int

long long int

標準同時規定,每一種有符號整型都有一種對應的無符號整型版本,而且有符號整型與其對應的無符號整型具有相同的儲存空間大小。

7、巨集__cplusplus

在c/c++混合編寫的**中,我們經常會在標頭檔案中看到如下的宣告:

#ifdef __cplusplus

extern "c"

#endif

由於extern "c"可以抑制c++對函式名、變數名等符號進行名稱重整(name mangling),因此編譯出的c目標檔案中的變數,函式名稱等等符號都是相同的,聯結器可以

可靠的對兩種型別的目標檔案進行連線,這樣該做法成為c與c++混用標頭檔案的典型做法。

tips:在c++03標準中,__cplusplus的值被預定為199711l,在c++11中,巨集__cplusplus被預定義成201103l。那麼可以利用這個巨集來檢查編譯器是否支援c++11新標準。

#if __cplusplus < 20131103l

#error "should use c++ 11 implementation"

#endif

這裡,使用了預處理指令#error,使得不支援c++11時,編譯報錯並且終止編譯。

3、斷言assert

assert是一種邊程式設計中常用的手段。用於排除在邏輯上不應該產生的情況。在c++中標準在或者標頭檔案中為程式設計師提供了assert巨集,用於在執行時進行斷言。

#include using namespace std;

double div(double a,double b)

int main()

static_assert在c++11中定義了乙個static_assert,這個宣告對於模板的除錯非常有用,編譯器快速執行這個常量表示式引數(不能依賴模板引數)。否則編譯器當模板例項化時執行這個常量表示式的引數。

#include #include using namespace std;

templateint bit_copy(t& a, u& b)

;int main()

在編譯的過程中就會出現如下的錯誤資訊:

c99和c 11的差異之一

include void main printf hello world.n gcc hello.c o hello std c99 編譯通過。但通過如下編譯則失敗 g hello.c o hello std c 11 失敗資訊為 hello.c 3 11 error main must retur...

偶爾回顧一下C99先於C11(三)

結構 typedef 結構struct 關鍵字 struct 用來訪問struct成員的運算子是 不知道為什麼用了鍊錶以後忽然發現不會訪問結構體成員了。可以使用 對結構體成員值進行初始化 struct book struct book unix 結構陣列 struct book unix max u...

C99標準之前沒有bool型別(C99提供)

我們知道在c 裡有專門的bool型別,用來表示真或假。但是在c語言裡沒有這樣的型別。表示式的值0為假,非0為真。所以條件判斷語句 if while 非常靈活,甚至乙個指標型別都可以是條件表示式。為了使程式更清晰,我們常常會給出如下的巨集定義 typedef int bool define true ...