Строковые литералы обязательно считаются смежными (и, следовательно, сцепленными), если они разделены символом новой строки? - PullRequest
3 голосов
/ 26 августа 2011

Это, я считаю, педантичный вопрос. Однако, поскольку часто задаваемые вопросы, по-видимому, не запрещают педантизм, я продолжу и спрашиваю, так как я действительно заинтересован в ответе.

Я пытаюсь прочитать и понять (большую часть) стандарт C99 (ISO / IEC 9899: 1999). Мне в основном интересно, строго ли это соответствует коду:

printf("String literal 1 "
"String literal 2.\n");

Или должен быть экранирован перевод строки следующим образом:

printf("String literal 1 "\
"String literal 2.\n");

Соответствующим разделом стандарта представляется раздел 5.1.1.2, в котором описаны этапы перевода. На втором этапе каждый символ "\", за которым следует символ новой строки, удаляется, объединяя строки в одну строку. Затем в фазе 6 смежные строковые литеральные токены объединяются.

Таким образом, чтобы первый пример кода соответствовал, я вижу два варианта: либо строковые литералы, разделенные новой строкой, считаются смежными, либо символы новой строки удаляются на одном из предыдущих этапов перевода.

Так кто-нибудь знает, можно ли считать приведенный выше пример кода строго соответствующим в этом контексте, и если да, то есть ли в стандарте что-то, что делает это абсолютно ясным?

Ответы [ 4 ]

2 голосов
/ 26 августа 2011

Я считаю, что они оба строго соответствуют. \ Отличается от конкатенации строковых литералов. Итак, ваш первый пример определенно хорош: между литералами есть символ новой строки, который является пробелом и, таким образом, образует «последовательность символы пробела ", как указано в 5.1.1.3.

Стандарт C в 5.1.1.2 немного неясен относительно \ хотя, поскольку он смутно предполагает, что символ новой строки удаляется так же, как и обратный слеш. Но в данном конкретном случае не должно иметь значения, есть ли пробельные символы между строковыми литералами или нет, я считаю, что ваш первый пример будет интерпретирован как

"Строковый литерал 1" "Строковый литерал 2. \ n"

, что в свою очередь приводит к ожидаемому результату.

2 голосов
/ 26 августа 2011

Да, новая строка - это просто пробел.Итак, ваш первый пример эквивалентен

printf("String literal 1 " "String literal 2.\n");.

1 голос
/ 26 августа 2011

Чтобы ответить формально на ваш последний вопрос, да, и вы указываете на правильный параграф в стандарте.

Теперь, почему бы не использовать обратную косую черту, как во втором фрагменте кода? Это просто бесполезно!

Обратная косая черта + EOL имеет значение только в очень немногих случаях, например при определении макроса в несколько строк при сохранении четкого отступа (и я не могу думать ни о каких других случаях). Вы можете фактически поставить обратную косую черту в конце всех строк, она будет компилироваться без проблем, если вы используете нормальный отступ. Вы можете даже поставить обратную косую черту + EOL между всеми символами вашего файла! printf("..."); как это совершенно правильно:

p\
r\
in\
t\
f\
("..\
.")\
;`
1 голос
/ 26 августа 2011

Я не могу доказать это с помощью параграфов стандарта, но две альтернативы эквивалентны.

Новая строка не является частью строк и поэтому не влияет на них.

...