程序编译过程中编码的作用

在读过编码与编码一文中,我们介绍了不同情况下编码所指代的不同含义,这里我们主要谈一谈,在程序编译的过程中,编码所起到的作用。首先我们要阐述如下几个定义:

  • 源文件编码:文件其实就是一堆字节所组成的,生成这些字节序列的方式即源码编码。
  • 编译器执行编码:编译器最终生成执行文件时的编码。

总结来看,编译过程中,编译器通过识别源文件的编码,将其按照执行编码进行转换输出,生成目标文件,最终目标文件经过链接生成可执行程序。所以当我们程序运行后,程序内部的各种数据,均是执行编码,而不是源码编码。那么不同的编译器是如何识别源文件编码并如何设置执行编码呢?

MSVC

  • 识别源文件:可以正确识别UTF-8 with BOM。否则编译器一概不识别,全部当做locale(简体中文系统即为GB2312)处理。
  • 执行编码:VS2005以上,无论源码如何,执行编码均为locale。

由此看来,大微软的编译器果然性格孤僻,要求严苛。那么我们如何设置执行编码呢?

设置

  1. C++11中,u8uU等前缀,可告知编译器按照何种执行编码输出此字符串。分别对应UTF-8UTF-16UTF-32
  2. 可设置当前文件执行编码:
    1
    2
    3
    #if _MSC_VER >= 1600
    #pragma execution_character_set("utf-8")
    #endif

GCC

  • 识别源文件:如无特殊设置,认为源码均是UTF-8 without BOM
  • 执行编码:如无特殊设置,默认均为UTF-8 without BOM

GCC这种全部统一为UTF-8格式,对我们来说很是方便。所以我们的开发中,建议全部使用UTF-8格式,当然这里的UTF-8格式,指的是标准格式,即无BOM

设置

  • -finput-charset 指定源文件的编码。
  • -fexec-charset 指定多字节字符串(const char*)常量在编译后的程序里保存的编码集。
  • -fwide-exec-charset 指定宽字节字符串(const wchar_t*)常量在编译后的程序里的保存的编码集。