![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Лично я на практике не встречал компилятора, который бы запретил такие действия или сделал их неправильно. Возможно теперь буду знать один - студию. Я начинал с турбо си, и в одном из учебников даже разбирался код, меняющий строку (не помню для чего, помню, что экономил память). ИМХО Такие действия допустимы в плане ненарушения стандарта, но бессмыслены во всех остальных планах. |
|||
|
||||
| nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 19 Всего: 181 |
gcc 4.1.1 тоже вылетает
ЗЫ. но не всегда, только без оптимизации, с оптимизацией выводит оба раза "!!!" Это сообщение отредактировал(а) nickless - 9.2.2007, 01:58 -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
|||
|
||||
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
| ip127001 |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 164 Регистрация: 24.11.2006 Где: Omsk Репутация: -2 Всего: -1 |
а с какой стати int *p=0; const int *p=0; одинаковыми стали...первый раз такое слышу!!!? Добавлено @ 11:26 они интерпритируются по разному... Добавлено @ 11:32
char *p="!!!"; const char *p1="!!!"; -----------------------это разные вещи --------------------
aqua currit et debere currere ut currere solebat |
||||
|
|||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
не перевирай мои слова, я это сказал только про char
почитай топик нормально, мы уже выяснили, что кроме чисто сишного турбо С, и борланда компиляторы не дают так делать, т.к считают это КОНСТАНТОЙ и из этого следует, что это идентичные вещи и никаких разных интерпретаций! |
||||
|
|||||
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Указатель никто и не пытался менять. Выясняли про собственно строку - в какую память он помещается. В стандарте написано, что инициализированный указатель на строку преобразовывается в неконстантный указатель, за исключением случая, когда он объявлен как массив. Компиляторы дают компилировать код, но вылетает сама программа при работе. Борланд ведет себя как положено в такой ситуации - строка меняется спокойно. Константный указатель или нет - это по барабану, никто не мешает сделать указатель неконстантным, присвоить ему значение проинициализированного строкой и попытаться поменять строку. В общем то спор о том, что можно или нет менять сами строки, зашитые в коде программы. В двух случаях происходит вылет или некорректная работа (на мой взгляд самая опасная ситуация - не можешь сделать, тогда уж вылетай с исключением, а не парь мозги программисту. А то получится на борланде работает, а в студии работает неправильно. Это некрасиво). А по поводу к чему преобразовывается - посмотрел используя type_id. Указатель вида char*p = "jsjsjsj"; и просто char *p имеют одинаковый тип (по крайней мере в борланде). |
|||
|
||||
| ip127001 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 164 Регистрация: 24.11.2006 Где: Omsk Репутация: -2 Всего: -1 |
а причем тут область памяти....ты не путаешь указатель на константу с константным указателем? --------------------
aqua currit et debere currere ut currere solebat |
|||
|
||||
| MAKCim |
|
||||||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
есть разница между целочисленной константой и литеральной
если есть целочисленная константа
то компилятору не составит труда в качестве одного из операндов команды записать непосредственно 5, потому что это значение константы известно код
может выглядеть так
со строковыми литералами сложнее: непосредственно ее в команду никак не подставишь в отличие от целочисленной константы, поэтому она помещается в read-only секцию данных а в качестве операнда используется ее адрес в этой секции для GCC это будет так для кода
при этом при загрузке исполняемого файла и просмотре заголовков секций находится read-only секция и ее содержимое помещается в какую-то физическую страницу памяти, а в соответствующем этой странице элементе таблицы страниц сбрасывается флаг W, и дальнейшее обращение к ней с целью записи приводит к #PF А то, что какой-то Borland допускает изменение константной строки, то это говорит о "качестве" компилятора Это сообщение отредактировал(а) MAKCim - 10.2.2007, 11:03 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||||||
|
|||||||||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
На мой взгяд следовало бы вообще запретить
только
|
||||
|
|||||
| Anikmar |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Стало быть так: если мы объявляем массив с инициализацией - его менять можно?
А если строку (которая тоже является массивом) то нельзя? Если я пишу так
Объясните где тут логика и чем строка отличается от массива?! Если я хочу инициализировать массив символов строкой - то в чем собственно проблема? Почему я потом не могу ее поменять?
Остаюсь при своем мнении - Борланд позволяет делать то, что не запрещено стандартом и он тут абсалютно прав. Добавлено @ 12:32 Делаю так - и все в порядке?
Мы говорим не о возможности изменить УКАЗАТЕЛЬ, а о возможности изменить область памяти, на которую он ссылается! |
||||||
|
|||||||
| MAKCim |
|
||||||||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
строка - константна по своей природе и располагается в read-only области памяти (при выполнении программы) в этом случае мы просто получаем ее адрес и изменить не можем
а в этом создаем копию строки в стеке (read-write область памяти)
т. е грубо говоря компилятор генерирует приблизительно такой код
и дальше можем изменять любой элемент a конструкция же
вообще банально проста (даже нет никакой символьной строки - просто символы)
Это сообщение отредактировал(а) MAKCim - 10.2.2007, 13:09 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||||||||
|
|||||||||||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
он не размещает константу (в данном случае символьную) в read-only секции данных - вот здесь его "хорошие" качества проявляются -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Это из чего следует? Я программист. Мне нужен строка флагов. Я могу ее создать двумя способами: char Options[] = "AAABBBCCDDEEFF"; или char *Options = "AAABBBCCDDEEFF"; Язык мне это разрешает, никакого запрета нет. Если абстрагироваться от мысли, что строка, это обязательно текстовая константа, выводимая на экран и рассматривать ее как инициализированный массив char - то все в порядке. Я не говорю, что так нужно делать. Я говорю о том, что теоретически можно. Но не нужно. И в некоторых учебниках по си (конечно, старых) укаазывалось, что данный код необходимо применять с осторожностью, особенно, если указана опция соединять одинаковые строки. Вот тут для меня загадка. И это, называется оптимизацией? Зачем две одинаковые строки в памяти? Резюме: мы такой баян растянули - что скоро остальные смеяться будут. Все равно каждый останется при своем мнении. Я остаюсь при таком: Делать так не стоит - так как непринято, противоречит хорошему тону программирования и т.п. Но к ошибке приводить это также не должно. |
|||
|
||||
| MAKCim |
|
||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
из того, что ты не можешь написать
равно как
это пример, естественно оптимизация возможна, но факт остается фактом: в одном случае мы используем указатель на строку в read-only секции, в другом - мы ее создаем (а уж с оптимизацией или нет - зависит от компилятора) должно это не тот случай, где возможны мнения -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||
|
|||||||
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Да ладно уж. Мнения возможны всегда, даже если они неправильбные - это просто ошибочные мнения. "bla-bla-bla"[0] - Такая конструкция запрещена синтаксисом самого языка. Что не запрещено стандартом должно быть разрешено. Никто не давал права трактовать стандарт по своему усмотрению. Я ничего не нашел в стандарте по поводу запрета изменения строки. Конечно, этот способ скорее пережиток Си и MSDOS, но ничего криминального я не вижу. Моя память - что хочу то и делаю! |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |