Здравствуйте, ariets, Вы писали:
A>По поводу области памяти: их вообще 5 — константные данные, стек, свободная динамическая память, куча, глобальная/статическая.
Это всё конечно очень интересно, но вопрос-то не про то, вроде...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>В С строковые литералы не константны по типу (т.е. в C это 'array of char' а не 'array of const char'). Тем не менее и в С модификация строкового литерала запрещена, т.е. четко сказано, что попытка модификации строкового литерала приводит к неопределенному поведению.
В ANSI стандарте? Точно написано? Я понмю, что у всех компиляторов была опция "можно совмещать совпадающие строковые литералы", и припоминаю проги, которые использовали литералы, как буферы в памяти...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Инициализация массива строк
От:
Аноним
Дата:
11.03.09 19:52
Оценка:
W>Но почему: W>
W>char *msgs[]={"123"}; // указатель на массив КОНСТАНТНЫХ строк
W>
W>являются КОНСТАНТНЫМИ стоками W>ведь компиляторы не ругаются W>и даже в некоторых случаях все работает: W>BC31 — выдает рабочую прогу W>VC6 — release-работает, debug-нет W>gcc — нет
потому что модификация константы — UB
Re[3]: Инициализация массива строк
От:
Аноним
Дата:
11.03.09 20:04
Оценка:
Кё>В специфике операционной системы, если быть точнее. Если предварительно сменить защиту памяти на секции константных данных, то можно будет спокойно писать туда без access violation.
и потом нарваться на спецэффекты:
char *a = "aaa";
a[2] = b;
printf("aaa");
А на экран выведется 'aab'.
А если эти строки раскиданы по проекту то заколебаетесь баг фиксить.
А>>А на экран выведется 'aab'.
MS>Вовсе не факт, что компилятор совместит две одинаковые строковые литеры. MS>Зависит от его возможностей и ключей.
это и называется UB
Re[5]: Инициализация массива строк
От:
Аноним
Дата:
11.03.09 21:51
Оценка:
MS>Вовсе не факт, что компилятор совместит две одинаковые строковые литеры. MS>Зависит от его возможностей и ключей.
даже если не совместит (если насильно выключить strings pooling) можно будет нарваться на другую совсем неочевидную ситуевину:
Здравствуйте, Аноним, Вы писали:
А>Догадайтесь что получим в stdout выхлопе, даже если компилятор не сделает strings pooling и не разместит их в RO памяти.
Дык это же фича!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, winogr, Вы писали:
W>попробуй скомпилить W>
W>char s[]="123";
W>s++;
W>
В данном случае s — это массив, а не указатель (ни константный, ни неконстантный). Со всеми вытекающими.
Просто за счет стандартного преобразования array-to-pointer conversion массив в ряде случаев ведет себя как указатель.
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, winogr, Вы писали:
W>>попробуй скомпилить W>>
W>>char s[]="123";
W>>s++;
W>>
B>В данном случае s — это массив, а не указатель (ни константный, ни неконстантный). Со всеми вытекающими. B>Просто за счет стандартного преобразования array-to-pointer conversion массив в ряде случаев ведет себя как указатель.
есть три варианта:
char *s="123"; // указатель (но можно только читать)
char bs[]="123";
char *s=bs; // указатель
char s[]="123"; // массив (т.к. s нельзя менять я назвал его константым указателем)
первый и второй дают указатели
третий не является их эквивалентом так значение s нельзя изменить
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>В С строковые литералы не константны по типу (т.е. в C это 'array of char' а не 'array of const char'). Тем не менее и в С модификация строкового литерала запрещена, т.е. четко сказано, что попытка модификации строкового литерала приводит к неопределенному поведению.
E>В ANSI стандарте?
Да, именно там.
E>Точно написано?
Абсолютно точно. Даже в замшелом С89/90: "6.1.4 String Literals [...] If the program attempts to modify a string literal of either form, the behavior is undefined".
E>Я понмю, что у всех компиляторов была опция "можно совмещать совпадающие строковые литералы",
Эта опция влияет не только на результаты модификации литералов, но и на адресные свойства литералов, т.е. ее "ценность" не сводится только к вопросам модификации.
У компиляторов в дополнение к этому есть еще бывает опция, явно делающая строковые литералы модифицируемыми. Тем не менее к стандартному все С это отношения не имеет.
E>и припоминаю проги, которые использовали литералы, как буферы в памяти...