Лучший способ ответить на ваш вопрос — переписать его как программу, которая идентично компилируется при использовании компилятора «C» или «C++». Я предполагаю, что вы используете GCC, но другой (правильно написанный) компилятор Цепочки инструментов должны давать аналогичные результаты.
Сначала я рассмотрю каждый пункт, который вы изложили, затем я дам программу, которая дает ответ (и доказательство).
- Насколько я могу судить, до C++11 строковые литералы обрабатывались почти точно так же, как между C и C++.
Их по-прежнему можно обрабатывать таким же образом, используя различные параметры командной строки, в этом примере я буду использовать «-fpermissive» (обман). Вам лучше выяснить, почему вы получаете предупреждения, и написать НОВЫЙ код, чтобы избежать ЛЮБОГО предупреждения; используйте только «читы» CLP для компиляции СТАРОГО кода.
Правильно пишите новый код (никаких читов и предупреждений, чтобы не было Ошибок).
- Теперь я признаю, что существуют различия между C и C++ в обработке широких строковых литералов.
Там не должно быть (много различий), так как вы можете обмануть большинство или все из них в зависимости от обстоятельств. Обманывать нехорошо, учитесь программировать правильно и следуйте современным Стандартам, а не ошибкам (или неловкости) прошлого. Вещи делаются определенным образом, чтобы быть полезными как для вас, так и для компилятора в некоторых случаях (помните, что ВЫ не единственный, кто «видит» ваш код).
В этом случае компилятору требуется достаточно места, чтобы выделить строку с "0" (нулевым байтом). Это позволяет использовать функцию печати (и некоторые другие) без указания длины строки.
ЕСЛИ вы просто пытаетесь скомпилировать существующую Программу, полученную откуда-то, и не хотите ее переписывать, вы просто хотите ее скомпилировать и запустить, затем используйте читы (если необходимо), чтобы обойти предупреждения и принудительно компиляция в исполняемый файл.
- Остальное, что вы написали...
No.
.
См. этот пример программы. Я немного изменил ваш вопрос, чтобы превратить его в программу. Результат компиляции этой Программы компилятором "C" или C++ идентичен.
Скопируйте и вставьте приведенный ниже пример текста программы в файл с именем «test.c», затем следуйте инструкциям в начале. Просто «пометьте» файл, чтобы вы могли прокрутить его назад (и увидеть его), не открывая текстовый редактор, затем скопируйте и вставьте каждую строку, начиная с команд компилятора (следующие три).
Обратите внимание, что, как указано в комментариях, выполнение этой строки "g++ -S -o test_c++.s test.c" приводит к ошибке (с использованием современного компилятора g++), поскольку длина контейнера недостаточна для хранения строки.
Вы должны уметь читать эту Программу, и на самом деле вам не нужно ее компилировать, чтобы увидеть Ответ, но она скомпилирует и выдаст вывод, который вы можете изучить, если захотите.
Как вы можете видеть, длина переменной «str1» недостаточна для хранения строки, когда она завершается нулем, что приводит к ошибке на современном (и правильно написанном) компиляторе g++.
/* Answer for: http://stackoverflow.com/questions/23145793/string-literal-differences-between-c-and-c
*
* cat test.c
* gcc -S -o test_c.s test.c
* g++ -S -o test_c++.s test.c
* g++ -S -fpermissive -o test_c++.s test.c
*
*/
char str1[3] = "1ab";
char str2[4] = "2ab";
char str3[] = "3ab";
main(){return 0;}
/* Comment: Executing "g++ -S -o test_c++.s test.c" produces this Error:
*
* test.c:10:16: error: initializer-string for array of chars is too long [-fpermissive]
* char str1[3] = "1ab";
* ^
*
*/
/* Resulting Assembly Language Output */
/* .file "test.c"
* .globl _str1
* .data
* _str1:
* .ascii "1ab"
* .globl _str2
* _str2:
* .ascii "2ab\0"
* .globl _str3
* _str3:
* .ascii "3ab\0"
* .def ___main; .scl 2; .type 32; .endef
* .text
* .globl _main
* .def _main; .scl 2; .type 32; .endef
* _main:
* LFB0:
* .cfi_startproc
* pushl %ebp
* .cfi_def_cfa_offset 8
* .cfi_offset 5, -8
* movl %esp, %ebp
* .cfi_def_cfa_register 5
* andl $-16, %esp
* call ___main
* movl $0, %eax
* leave
* .cfi_restore 5
* .cfi_def_cfa 4, 4
* ret
* .cfi_endproc
* LFE0:
* .ident "GCC: (GNU) 4.8.2"
*
*/
person
Rob
schedule
22.05.2014
const char[N]
противchar[N]
— огромная разница. Правило, запрещающее модификацию строковых литералов в C++, — это правило, запрещающее модификациюconst
объектов. Вы не найдете никаких особых случаев C++, таких как правило C, специально запрещающее запись в память, где хранятся строковые литералы. - person Ben Voigt   schedule 18.04.2014char str[4] = "abc";
это не присваивание, это инициализация. - person Yu Hao   schedule 18.04.2014char*
, даже если объект является константным литералом, и можно инициализировать массив, который может содержать все, кроме терминатора, с помощью строковый литерал. - person Deduplicator   schedule 18.04.2014const
. - person Ben Voigt   schedule 18.04.2014char [N]
, как сказал Зан в вопросе. - person Ben Voigt   schedule 18.04.2014const char[]
. - person FoggyDay   schedule 18.04.2014const
в C ++ имеет гораздо больше эффектов, чем просто альтернативный способ указать правило C, что они не могут быть изменены. По крайней мере, я думаю, что это должно иметь значение для целочисленных константных выражений и удобства использования сconstexpr
инициализацией. - person Ben Voigt   schedule 18.04.2014const
действительно имеет значение в C ++, что, я думаю, я признаю, но между C и C ++ я не думаю, что это так, потому что, хотя терминология может немного отличаться, результаты точно такие же. - person Zan Lynx   schedule 18.04.2014L"Hello, " "world"
недопустимо в C, но допустимо в C++. - person Mohit Jain   schedule 14.05.2014char
, чем на вопрос о строковых литералах. - person tenfour   schedule 21.05.2014