Форум программистов, компьютерный форум CyberForum.ru

[C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
12.10.2009, 00:31     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #1
Заметил такую странность:
Это проходит компиляцию
C++
1
bool *b = false;
А это нет
C++
1
bool *b = true;
Код
error: cannot convert ‘bool’ to ‘bool*’ in initialization
Компилятор g++.Почему это вообще проходит компиляцию в каком либо виде?Я понимаю,это как-то связано с инициализацией указателя,а false типа трактуется как NULL?Хотелось бы знать,как точно это работает.
У меня случайно сначала так вышло,но вообще подразумевалось
C++
1
bool *b = new bool(false);
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.10.2009, 00:31     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя?
Посмотрите здесь:

False,True C++
Кто объяснит почему true == false ? C++
вывод true и false C++
Кто-нибудь знает, что это за ошибка? C++
C++ Глюк false = true == true;
С++. вывод true/false C++
Кто-нибудь может переделать задачу со структур на классы? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Lolcht0
123 / 121 / 5
Регистрация: 30.03.2009
Сообщений: 766
12.10.2009, 00:36     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #2
потому что у тебя false == 0

получается, что
C++
1
bool *b = false;
эквивалентоно
C++
1
bool *b = 0;
эквивалентно
C++
1
bool *b = NULL;
что допустимо

а вот
C++
1
bool *b = true;
может быть эквивалентно, например,
C++
1
bool *b = 1;
указатель можно сделать null, но присваивать ему в лоб адрес - нехорошо
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
12.10.2009, 00:38  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #3
По идее false и NULL это не одно и тоже.Да и в C++ null не определён вроде,вот и спрашиваю.В-общем,мне как-то видится это нештатной ситуацией
Lolcht0
123 / 121 / 5
Регистрация: 30.03.2009
Сообщений: 766
12.10.2009, 00:46     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #4
ну приводится же int к bool всегда, и все к этому привыкли уже, так почему бы и обратно не приводилось?
Sich_Taras
14 / 14 / 1
Регистрация: 08.10.2009
Сообщений: 114
12.10.2009, 01:18     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #5
Если ты указателю присваиваешь значение 0 (a это и есть false), то это означает, что он не указывает ни на какую область памяти и это нормально. Но если ты хочешь присвоить указателю значение 1 (true), тоесть ты хочешь, чтобы он указывал на область памяти которая начинается с ячейки №1, то ты должен написать так:
C++
1
bool *string = (bool*)true;
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,353
Записей в блоге: 26
11.12.2009, 11:42     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #6
Цитата Сообщение от Sich_Taras Посмотреть сообщение
Если ты указателю присваиваешь значение 0 (a это и есть false), то это означает, что он не указывает ни на какую область памяти и это нормально. Но если ты хочешь присвоить указателю значение 1 (true), тоесть ты хочешь, чтобы он указывал на область памяти которая начинается с ячейки №1, то ты должен написать так:
Немного не так. По стандарту Си должно быть некоторое специальное значение указателя и чтобы ни один объект не мог иметь такой адрес. В заголовочных файлах такое значение должно быть описано как NULL. Если p - это некий указатель, то "if (p)" должно трактоваться как "if (p != NULL)". При этом стандарт не говорит, чему должен быть равен NULL. Для большинства "нормальных" систем NULL равен нулю. Но для некоторых процессоров это может быть не так. На сигнальных процессорах зачастую 0 является валидным адресом. Поэтому в качестве NULL может быть взято значение -1. У сигнальных процессоров мало памяти, а потому адрес 0xffff... как правило находится за рамками физической памяти процессора и поэтому удовлетворяет стандарту (т.е. не существует переменной или функции, адрес которой равен -1)

Когда-то #pragma искал примеры непереносимых кодов. Можно привести ещё пример. Предполагаем, что во всех трёх случаях делается сравнение с NULL

C
1
2
3
4
int *p;
if (p) ....         /* переносимый */
if (p!=NULL) ....   /* переносимый */
if (p!=0) ....      /* НЕ переносимый */
Ну и, соответственно, целочисленное значение, соответствующее NULL, можно присваивать в указатель любого типа без явного преобразования. В нашем случае NULL соотвествует нулю, а потому присваивание false отработало корректно. На вышеупомянутом сигнальном процессоре здесь так же произошла бы ошибка
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
11.12.2009, 15:39  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #7
>Немного не так. По стандарту Си должно быть некоторое специальное значение указателя и чтобы ни один объект не мог иметь такой адрес. В заголовочных файлах такое значение должно быть описано как NULL. Если p - это некий указатель, то "if (p)" должно трактоваться как "if (p != NULL)".

Точно. NULL не равен нулю(не всегда). По идее NULL должен (или нет?) быть определён как
C
1
#define NULL   (void *)0
Чтобы никуда не указывать.
Но я вроде читывал,что в некоторых реализациях компиляторов этим могли пренебречь (особенно в новых) и определить NULL как
C
1
#define NULL  0
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,353
Записей в блоге: 26
11.12.2009, 15:47     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #8
> Чтобы никуда не указывать

Формулировка неправильная. Просто из всего диапазона адресов выбирается некоторое значение и говорится, что у нас не существует ни одного объекта с таким адресом. Далее заводится макрос NULL с этим значением, а так же на это значение настраивается компилятор, чтобы адэкватно строить сравнения и не выдавать ошибки там где не надо.

Конкретное значение для NULL - зависит от платформы. Т.е. для всех "нормальных" платформ в качестве NULL выбирается ноль (и под такое значение настраивается макрос и компилятор). Для сигнальных процессоров выбирается другое значение.
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
11.12.2009, 15:49  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #9
Да,спасибо,я прочитал внимательнее твой пост
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,353
Записей в блоге: 26
11.12.2009, 15:51     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #10
Собственно макрос NULL придумали опять-таки по соображениям переносимости кода между платформами. Т.е. программист пишет код:

C
1
2
3
4
5
6
p = NULL;
...
if (p)
{
...
}
Но при этом на одной платформе NULL раскроется в (void*)0, а "if (p)" в "if (p != 0)". Но на другой платформе это может раскрыться в "p = (void*)-1" и "if (p != -1)", но это спрятано на уровне интерфейса и программных соглашений на архитектуру, которые учитывает компилятор. Т.е. указанный выше код будет правильно работать независимо от того, как всё это безобразие настроено
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
11.12.2009, 16:17  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #11
А ты на Багзилле в gcc зарегистрирован? Может,стоит написать им,чтобы компилятор хотя бы предупреждение выводил?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,353
Записей в блоге: 26
11.12.2009, 16:22     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #12
g++ всё делает согласно стандарту. Значение false эквивалентно нулю (что эквивалентно NULL), а потому такое присваивание можно делать без явного преобразования типа. А вот для true уже нельзя. Borland C++ работает ровно так же
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.11.2010, 23:20  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #13
Evg, я тут кое что накопал про NULL и 0. Выдержка из книги "Beej Guide to Network Programming"
If you set the fields in your struct timeval to 0, select() will timeout
immediately, effectively polling all the file descriptors in your sets. If you set the parameter timeout to
NULL, it will never timeout, and will wait until the first file descriptor is ready. Finally, if you don't care
about waiting for a certain set, you can just set it to NULL in the call to select().
То есть тут подчёркивается,что 0 и NULL - это не эквивалентные значения.
ForEveR
Модератор
Эксперт С++
 Аватар для ForEveR
7954 / 4716 / 318
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
04.11.2010, 23:25     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #14
#pragma, В Си действительно различны (ну как и говорил Evg, от архитектуры зависит).
В С++ его не рекомендуется использовать. Но определен он как #define NULL 0. Хотя не исключаю, что тоже может зависить от архитектуры
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.11.2010, 23:30  [ТС]     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #15
Хз,от чего это зависит,но select()-довольно часто используемая функция в linux.
про
C
1
#define NULL (void *)0
вроде уже писали.
Мне интересно,как они эти параметры сравнивают внутри select ..
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,353
Записей в блоге: 26
04.11.2010, 23:58     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #16
Про select. Там не то, о чём ты пишешь. Про ноль говорится, что если ПОЛЯ структуры забить нулями. А про NULL - если вместо указателя на заполненную структуру подсунуть NULL
Mr.X
Эксперт С++
 Аватар для Mr.X
3011 / 1667 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
05.11.2010, 00:52     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #17
Цитата Сообщение от #pragma Посмотреть сообщение
Заметил такую странность:
Это проходит компиляцию
C++
1
bool *b = false;
Согласно синтаксису C++, указателю можно присваивать либо адрес, либо нулевую константу. Никаких NULLов не предусмотрено. Правда, для особых фанатов Страуструп в своей книге пишет: «Гарантируется, что нет объектов с нулевым адресом. Следовательно, указатель, равный нулю, можно интерпретировать как указатель, который ни на что не ссылается.
В языке С было очень популярно определять макрос NULL для представления такого нулевого указателя. Так как в С++ типы проверяются более жестко, использование банального нуля вместо NULL приведет к меньшим проблемам. Если вы чувствуете, что просто обязаны определить NULL, воспользуйтесь
const int NULL = 0;
Модификатор const (§ 5.4) предотвращает ненамеренное замещение NULL и гарантирует, что NULL можно использовать везде, где требуется константа.» <Конец цитаты>
Ну а приведенное вами выражение не одного вас удивило. В книге «Дизайн и эволюция языка C++» Страуструп пишет: «Но меня по-прежнему удивляет правило, согласно которому результат вычисления любого константного выражения, равный 0, принимается в качестве нулевого указателя. Согласно этому правилу, 2-2 и ~-1 - нулевые указатели.» <Конец цитаты>
Видимо поэтому в новом стандарте предусмотрено специальное ключевое слово для обозначения пустого указателя.
KpeHDeJIb
 Аватар для KpeHDeJIb
56 / 56 / 3
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 02:27     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #18
В С++ NULL == 0 и компиляторов C++ для микропроцессоров не существует. Для Си есть, но там NULL хоть что-то значит. Однако в свежем стандарте С++, который готовится, будет таки специальная штука null, которая будет служить как раз для тех же целей что и NULL в Си.
ForEveR
Модератор
Эксперт С++
 Аватар для ForEveR
7954 / 4716 / 318
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
05.11.2010, 02:28     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #19
KpeHDeJIb, nullptr, а не null.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.11.2010, 03:05     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя?
Еще ссылки по теме:

C++ Преобразование времени (double. Может всё-таки кто-нибудь знает)
true and false C++
Задание со строками на true or false C++
C++ Задача на true or false
C++ Всем добрый день! Кто-нибудь знает как исправить это?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Mr.X
Эксперт С++
 Аватар для Mr.X
3011 / 1667 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
05.11.2010, 03:05     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? #20
Цитата Сообщение от KpeHDeJIb Посмотреть сообщение
В С++ NULL == 0
В стандарте этого нет. Там только сказано, что значение этого макроса зависит от реализации.
Yandex
Объявления
05.11.2010, 03:05     [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя?
Ответ Создать тему
Опции темы

Текущее время: 03:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru