Установка для charset значения «Not Set» просто означает, что ни один из макросов препроцессора _UNICODE и _MBCS не будет установлен. Это не влияет на то, какие наборы символов используются компилятором.
Двумя настройками, которые определяют, как байты вашего источника преобразуются в строковый литерал в программе, являются «набор символов источника» и «набор символов выполнения». Компилятор преобразует строковые литералы из исходной кодировки в кодировку выполнения.
Исходная кодировка:
Исходная кодировка - это кодировка, используемая компилятором для интерпретации байтов исходного файла. Он применяется не только к строковым и символьным литералам, но и ко всему остальному в источнике, включая, например, идентификаторы.
Если компилятор Visual Studio обнаруживает «сигнатуру» Unicode в исходном файле, он будет использовать соответствующую кодировку Unicode в качестве исходной кодировки. В противном случае он будет использовать кодировку кодовой страницы системы в качестве исходной кодировки.
Кодировка исполнения:
Кодировка выполнения - это кодировка, в которой компилятор хранит строковые и символьные литералы, так что строки и символьные данные, созданные литералами, будут кодироваться с использованием кодировки выполнения.
Компилятор Visual Studio использует кодовую страницу системы в качестве кодировки выполнения.
Когда Visual Studio выполняет преобразование строковых и символьных литеральных данных из исходной кодировки в кодировку выполнения, она заменит символы, которые не могут быть представлены в наборе кодов выполнения, на «?».
Итак, для вашего примера:
const char *c = "£";
Если исходный код сохранен в формате Microsoft "UTF-8 с подписью", а ваша система использует CP1252, как это делают большинство систем на Западе, строковый литерал будет преобразован в:
0xA3 0x00
С другой стороны, если набор символов выполнения не содержит символа «£», например cp1251 (кириллица, используемая в русской локали Window), строковый литерал будет иметь следующий вид:
0x3F 0x00
Если вы хотите избежать зависимости от кодировки исходного кода, вы можете использовать универсальные имена символов (UCN):
const char *c = "\u00A3"; // "£"
Если вы хотите гарантировать представление в формате UTF-8, вам также необходимо избегать зависимости от кодировки выполнения. Вы можете сделать это вручную, закодировав его:
const char *c = "\xC2\xA3"; // UTF-8 encoding of "£"
C ++ 11 представляет строковые литералы UTF-8, которые будут лучше, если ваш компилятор их поддерживает:
const char *c = u8"£";
или
const char *c = u8"\u00A3"; // "£"