Создают ли бесполезные обратные косые черты четко определенные строковые константы? - PullRequest
6 голосов
/ 11 марта 2020

Оба, C и C ++, поддерживают, по-видимому, эквивалентный набор escape-последовательностей, таких как \b, \t, \n, \" и другие, начинающиеся с символа backsla sh (\) , Как обрабатывается обратный символ sh, если следует нормальный символ? Насколько я помню из нескольких компиляторов escape-символ \ молча пропускается. На cppreference.com я читаю эти статьи

Я нашел только эту заметку (в статье C) о бесхозных обратных косых чертах

ISO C требует диагностики c, если соблюдается обратная косая черта sh любым символом, не указанным здесь: [...]

над справочной таблицей. Я также посмотрел некоторые онлайн-компиляторы

C демо

#include <stdio.h>

int main(void) {
    // your code goes here
    printf("%d", !strcmp("\\ x", "\\ x"));
    printf("%d", !strcmp("\\ x", "\\\ x"));
    printf("%d", !strcmp("\\ x", "\\\\ x"));
    return 0;
}

C ++ демо

#include <iostream>
#include <string>
using namespace std;

int main() {
    cout << (string("\\ x") == "\\ x");
    cout << (string("\\ x") == "\\\ x");
    cout << (string("\\ x") == "\\\\ x");
    return 0;
}

Оба обрабатывают "\\ x" и "\\\ x" как эквивалентные (вид) предупреждения с помощью подсветки синтаксиса. IOW "\\\ x" было преобразовано в "\\ x".

Можно ли предположить, что это определенное поведение?

Разъяснение (правка)

  • Я не спрашиваю о явно недопустимых строковых литералах, таких как "\".
  • Я осознаю , что сирота backsla sh несколько проблематична c.
  • Я хочу знать, является ли результат, созданный компилятором константой, определенным .

Редактировать # 2: Сосредоточиться еще больше на генерируемой константе (и портативность).

Ответы [ 2 ]

4 голосов
/ 11 марта 2020

Ответ - нет. Это недопустимая C программа и неопределенное поведение C ++ one.

C Standard

говорит, что это синтаксически неправильно (подчеркните мой), он не производит действительный токен, поэтому программа недействительна:

5.2.1 Наборы символов

2 / В символьной константе или строковом литерале члены набора символов выполнения должны быть представлены соответствующими элементами исходного набора символов или escape-последовательностями, состоящими из обратного знака sh \, за которым следует один или несколько символов.

6.4.4.4 Символьные константы

3 / Одинарная кавычка ', двойная кавычка', знак вопроса?, Обратная коса sh \ и произвольные целочисленные значения представляются в соответствии со следующей таблицей escape-последовательностей:

  • одинарная кавычка '\'
  • двойная кавычка "\"
  • вопрос отметка ? \?
  • backsla sh \ \\
  • восьмеричный символ \octal digits
  • шестнадцатеричный символ \xhexadecimal digits

8 / Кроме того, символы, не входящие в базовый набор символов c, могут быть представлены универсальными именами символов, а некоторые неграфические символы c могут быть представлены escape-последовательностями, состоящими из обратной косой черты sh \, за которой следует строчная буква : \ a, \ b, \ f, \ n, \ r, \ t и \ v. Примечание: Если за бэкслой следует любой другой символ sh, результат не является токеном и требуется диагностика c .

C ++ стандарт

говорит по-другому (подчеркиваю мое):

5.13.3 Литералы символов

7 / Определенно неграфические c символы, одинарные кавычки ', двойные кавычки ", знак вопроса?, 25 и обратная коса sh \, могут быть представлены в соответствии с таблицей 8. Двойная кавычка" и знак вопроса?, могут быть представлены как сами по себе или как escape-последовательности \ "и \? соответственно, но одинарная кавычка 'и обратная коса sh \ должны быть представлены escape-последовательностями \' и \ соответственно. Escape-последовательности, в которых Символ после обратного знака sh не указан в Таблице 8 и поддерживается условно, с определяемой реализацией семантикой . В escape-последовательности указан один символ.

Таким образом, для C ++ вам потребуется взглянуть на тебя Руководство по компилятору r для semanti c, но программа синтаксически допустима.

3 голосов
/ 11 марта 2020

Вам необходимо скомпилировать с соответствующим компилятором C. Различные онлайн-компиляторы, как правило, используют g cc, который по умолчанию настроен на "слабый нестандартный режим", он же GNU C. Это может включать или не включать некоторые нестандартные escape-последовательности, но это также не будет приводить к ошибкам компилятора, даже если вы нарушаете язык C - вы можете избежать «предупреждения», но это не делает код действительным C.

Если вы скажете g cc вести себя как соответствующий компилятор C с -std=c17 -pedantic-errors, вы получите эту ошибку:

error: unknown escape sequence: '\040'

040 восьмерично для 32, что является кодом ASCII для ' '. (По некоторым причинам g cc использует восьмеричные нотации для escape-последовательностей внутри, возможно, потому что \ 0 является восьмеричным, я не знаю почему.)

...