gcc中关于C/C++标准的选项

man gcc里面说到gcc使用指定的标准编译C/C++的选项是:-std=standard,其中standard可以是

c89(传说中的c89)
iso9899:1990
    Support all ISO C90 programs (certain GNU extensions that conflict with ISO C90
    are disabled). Same as -ansi for C code.

iso9899:199409
    ISO C90 as modified in amendment 1.

c99(传说中的c99)
c9x
iso9899:1999
iso9899:199x
    ISO C99.  Note that this standard is not yet fully supported; see
    <http://gcc.gnu.org/gcc-4.2/c99status.html> for more information.  The names c9x
    and iso9899:199x are deprecated.

gnu89
    GNU dialect of ISO C90 (including some C99 features). This is the default for C code.

gnu99
gnu9x
    GNU dialect of ISO C99.  When ISO C99 is fully implemented in GCC, this will
    become the default.  The name gnu9x is deprecated.

c++98
    The 1998 ISO C++ standard plus amendments. Same as -ansi for C++ code.

gnu++98
    GNU dialect of -std=c++98.  This is the default for C++ code.

还有一个选项就是-ansi,上面也说到了。

以上是在gcc4.2.4里面看到的。

C语言结构体赋值相关

看UNPv1的时候,在第四章看到ipv6结构体的赋值,里面说到C语言的结构体变量无法直接赋值为该结构的常值结构,但是可以用变量赋值,并且如果是初始化的时候也是可以的,废话少说,还是上代码说的明白:

typedef struct A { 
        int a;
        char b;
} A;

int main()
{
    
        A b = {2, 'b'}; //OK
        A a = {1, 'a'}; //OK
        /* a = {1, 'b'} //非法,结构体赋值不能用常量结构赋值,不过可以这样: */
        a = b; /* 合法,b是同类型的结构体变量 */

        return 0;
}

C语言预处理指令总结

        预处理指令严格来说不属于程序语句的一部分,所有的预处理语句在程序编译之前被预处理器处理完成。每一条预处理语句总是以"#"字符开始,并且不能超过一行,一旦遇到换行符语句就被当做结束。一般来说,预处理语句的后面不能加分号。另外,唯一的一种能将预处理语句扩展到多行的办法就是在换行符之前加一个反斜杠('\')。

 

宏定义(#define,#undef)

#define指令主要用于定义常量还有就是定义带有参数的”函数“。

#define PI 3.1416

#define MAX(a,b) (a)>(b)?(a):(b)

有一个值得注意的就是括号的使用。

#undef用于取消之前定义过的宏定义。

”函数“型宏定义接受两个特殊的运算符(#,##)

使用#使得#之后的第一个参数作为一个带引号的字符串返回。例如

#define str(x) #x
cout << str(test);

被处理后相当于

cout << "test";

使用##连接##之前和之后的内容。例如

#define glue(a,b) a ## b
glue(c,out) << "test";

处理后相当于

cout << "test";

 

条件包含指令(#ifdef, #ifndef, #if, #endif, #else ,#elif) 

#ifdef micro
some codes here
#endif

如果宏被使用#define 定义,命令后边的代码被编译。

#if expression
some code here
#endif

如果表达式为真,命令后边的代码被编译。

#ifndef跟#ifdef相反。

#if 和#elif后面 的表达式用于比较操作时候只允许用整数。例如

#if VERBOSE == "on" // NOT ALLOWED
  print("trace message");
#endif
#if VERBOSE >= 2.0 // NOT ALLOWED
  print("trace message");
#endif

另外,#ifdef和#ifndef也可以分别用运算符 defined!defined取得相同的效果。例如

#if !defined TABLE_SIZE
#define TABLE_SIZE 100
#elif defined ARRAY_SIZE
#define TABLE_SIZE ARRAY_SIZE
int table[TABLE_SIZE];


行控制(#line)

语法:

#line line_number "filename"

#line命令可以简单的改变下一行__LINE____FILE__的值,文件名是可选的,__LINE____FILE__表示当前文件名和当前行的行号。

这条命令

 #line 10 "main.cpp"

…改变更改下一行行号改为10,当前文件名为”main.cpp”。


错误指令(#error)

#error message

当编译器遇到#error命令的时候会被迫停止编译,并输出错误信息和出错行号

 

文件包含(#include)

最常用,一共有两种方式

#include "file"
#include <file> 

双引号表示在当前目录搜索,然后在系统定义的目录搜索,而尖括号表示直接在系统目录搜索。

 

Pragma 指令(#pragma)

 #pragma lexems

#pragma命令赋予程序员控制编译器的能力,由于#prama的实现依赖于编译器,使用方法因编译器而异。一个选项可能完全改变程序执行顺序。

 

预定义的宏名

    __LINE__
    __FILE__
    __DATE__
    __TIME__
    __cplusplus
    __STDC__
  • __LINE____FILE__ 变量记录了编译器的当前处理行和当前处理文件。
  • __DATE__ 变量包含当前文件被编译的日期,格式为:月/日/年。
  • __TIME__ 变量包含当前文件被编译的时间,格式为:时:分:秒。
  • __cplusplus 变量只有在C++程序中才被定义;一些老编译器也可以为c_plusplus
  • __STDC__ 变量在编译C程序的时候被定义,许多编译器在编译C++代码时也会定义此变量。

Reference:

  1. www.cppreference.com/wiki/cn/preprocessor/start
  2. en.wikipedia.org/wiki/C_preprocessor
  3. www.cplusplus.com/doc/tutorial/preprocessor/