Во-первых, я хочу сказать, что проблема, которую вы описываете, вряд ли имеет значение. Если вашему компилятору требуется спецификация UTF-8 для обработки файла как использующего кодировку UTF-8, то у вас не может быть файла, в котором отсутствует спецификация UTF-8, но где исходный код начинается с U+FEFF в кодировке UTF-8. . Если вашему компилятору не требуется спецификация UTF-8 для обработки файлов UTF-8, вам не следует помещать спецификации UTF-8 в исходные файлы (по словам Майкла Каплана, "ПРЕКРАТИТЕ ИСПОЛЬЗОВАТЬ БЛОКНОТ WINDOWS").
Но да, если компилятор удаляет спецификации, вы можете получить поведение, отличное от предполагаемого. Если вы хотите (неблагоразумно) начинать исходный файл с U+FEFF, но (благоразумно) отказываетесь помещать спецификации в исходный код, вы можете использовать универсальное символьное имя: .
Теперь о моем ответе.
Извлечение символов физического исходного файла не определяется стандартом C++. Объявление кодировки исходного файла для компилятора, форматы файлов для хранения физических исходных символов и сопоставление физических исходных символов файла с базовым исходным набором символов — все это определяется реализацией. Поддержка обработки U+FEFF в начале исходного файла как намека на кодировку лежит в этой области.
Если компилятор поддерживает необязательную спецификацию UTF-8 и не может отличить файл, в котором указана необязательная спецификация, от файла, в котором ее нет, но исходный код начинается с U+FEFF, то это дефект конструкции компилятора и, в более широком смысле. в идее самой спецификации UTF-8.
Чтобы интерпретировать байты данных как текст, необходимо знать кодировку текста, однозначно определенную авторитетным источником. (Вот статья, которая подчеркивает это.) К сожалению, до того, как этот принцип был понят, данные уже передавались между системами, и людям приходилось иметь дело с данными, которые якобы были текстом, но кодировка которых не обязательно была известна. Поэтому они придумали очень плохое решение: угадать. Набор методов, использующих спецификацию UTF-8, является одним из разработанных методов угадывания.
Спецификация UTF-8 была выбрана в качестве подсказки по кодировке по нескольким причинам. Во-первых, он не влияет на видимый текст и поэтому может быть преднамеренно вставлен в текст без видимого эффекта. Во-вторых, файлы, отличные от UTF-8, вряд ли будут содержать байты, которые будут ошибочно приняты за спецификацию UTF-8. Однако это не мешает использованию спецификации быть ничем иным, как угадыванием. Нет ничего, что говорило бы о том, что обычный текстовый файл ISO-8859-1 не может начинаться, например, с U+00EF U+00BB U+00BF. Эта последовательность символов, закодированная в ISO-8859-1, использует ту же кодировку, что и U+FEFF, закодированная в UTF-8: 0xEF 0xBB 0xBF. Любое программное обеспечение, которое полагается на обнаружение спецификации UTF-8, будет сбито с толку таким файлом ISO-8859-1. Таким образом, спецификация не может быть авторитетным источником, хотя предположения, основанные на ней, почти всегда работают.
Помимо того факта, что использование спецификации UTF-8 равносильно угадыванию, есть еще одна причина, по которой это ужасная идея. Это заключается в ошибочном предположении, что изменения в тексте, которые не влияют на визуальное отображение этого текста, вообще не имеют никакого эффекта. Это предположение может быть неверным всякий раз, когда текст используется для чего-то другого, кроме визуального отображения, например, когда он используется в тексте, предназначенном для чтения компьютером в качестве исходного кода.
Итак, в заключение: эта проблема со спецификацией UTF-8 не вызвана спецификацией C++; и если вы абсолютно не вынуждены взаимодействовать с безмозглыми программами, которые этого требуют (другими словами, программами, которые могут обрабатывать только подмножество строк Unicode, начинающихся с U+FEFF), не используйте спецификацию UTF-8.
person
bames53
schedule
22.11.2011