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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

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

12.10.2009, 00:31. Просмотров 2512. Ответов 26
Метки нет (Все метки)

Заметил такую странность:
Это проходит компиляцию
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);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.10.2009, 00:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос [C/C++]Компилятор g++.Странности с true и false.Кто нибудь может прокомментировать/повторить это у себя? (C++):

Кто объяснит почему true == false ? - C++
Спасайте! а то я щас повешусь от взрыва мозга! Кто объяснит вот что это за фигня. Когда я в программе пишу: char a = 0x64; ...

Если bool name=false, то !name это true? - C++
Добрый день! Привожу код, взятый из книги. Непонятны следующие строки bool found_one = false; строка 104 if( !found_one ) ...

Кто-нибудь может подробно объяснить, что такое allocators, зачем это и что с ними делать? Нигде не нашёл инфы - C++
Заранее спасибо.

Кто-нибудь знает, что это за ошибка? - C++
Кто-нибудь знает, что это за ошибка, когда она возникает и что делать? command line error MIDL1004: cannot execute C preprocessor...

Кто-нибудь может закоментировать код слэшами,пожалуйста? - C++
#include "wot.h" #include <stdio.h> #include <windows.h> #include <iostream> #include <stdlib.h> #include <conio.h> #include...

Кто-нибудь может переделать задачу со структур на классы? - C++
Огромное спасибо, кто откликнется. #include <stdio.h> #include <string.h> main() { struct ZNAK {

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

Точно. NULL не равен нулю(не всегда). По идее NULL должен (или нет?) быть определён как
C
1
#define NULL   (void *)0
Чтобы никуда не указывать.
Но я вроде читывал,что в некоторых реализациях компиляторов этим могли пренебречь (особенно в новых) и определить NULL как
C
1
#define NULL  0
0
Evg
Эксперт CАвтор FAQ
18029 / 6261 / 427
Регистрация: 30.03.2009
Сообщений: 17,200
Записей в блоге: 27
11.12.2009, 15:47 #8
> Чтобы никуда не указывать

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

Конкретное значение для NULL - зависит от платформы. Т.е. для всех "нормальных" платформ в качестве NULL выбирается ноль (и под такое значение настраивается макрос и компилятор). Для сигнальных процессоров выбирается другое значение.
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
11.12.2009, 15:49  [ТС] #9
Да,спасибо,я прочитал внимательнее твой пост
0
Evg
Эксперт CАвтор FAQ
18029 / 6261 / 427
Регистрация: 30.03.2009
Сообщений: 17,200
Записей в блоге: 27
11.12.2009, 15:51 #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)", но это спрятано на уровне интерфейса и программных соглашений на архитектуру, которые учитывает компилятор. Т.е. указанный выше код будет правильно работать независимо от того, как всё это безобразие настроено
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
11.12.2009, 16:17  [ТС] #11
А ты на Багзилле в gcc зарегистрирован? Может,стоит написать им,чтобы компилятор хотя бы предупреждение выводил?
0
Evg
Эксперт CАвтор FAQ
18029 / 6261 / 427
Регистрация: 30.03.2009
Сообщений: 17,200
Записей в блоге: 27
11.12.2009, 16:22 #12
g++ всё делает согласно стандарту. Значение false эквивалентно нулю (что эквивалентно NULL), а потому такое присваивание можно делать без явного преобразования типа. А вот для true уже нельзя. Borland C++ работает ровно так же
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.11.2010, 23:20  [ТС] #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 - это не эквивалентные значения.
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
04.11.2010, 23:25 #14
#pragma, В Си действительно различны (ну как и говорил Evg, от архитектуры зависит).
В С++ его не рекомендуется использовать. Но определен он как #define NULL 0. Хотя не исключаю, что тоже может зависить от архитектуры
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.11.2010, 23:30  [ТС] #15
Хз,от чего это зависит,но select()-довольно часто используемая функция в linux.
про
C
1
#define NULL (void *)0
вроде уже писали.
Мне интересно,как они эти параметры сравнивают внутри select ..
0
04.11.2010, 23:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.11.2010, 23:30
Привет! Вот еще темы с ответами:

Преобразование времени (double. Может всё-таки кто-нибудь знает) - C++
Как double сделать так, чтобы он работал по такому принципу. К примеру идет число 0,01...0,59 и после 0,59 переходило не в 0,60 , а в...

Всем добрый день! Кто-нибудь знает как исправить это? - C++
https://pp.vk.me/c625822/v625822049/3a869/cr3hbcL44_4.jpg Нарушение правил п.5.8. Запрещено публиковать ссылки на другие форумы, а...

Указатели и адреса: может кто-нибудь нормально по-человечески эту тему объяснить? - C++
Добрый вечер. Читаю вот книгу по Липманну и ничего не понимаю из этих слов, может кто нормально по-человечески объяснить? Спасибо. ...

Глюк false = true == true; - C++
Возник глюк, пишу: result.isPlus = this->isPlus == numberBigSize.isPlus; Поля "this->isPlus" и "numberBigSize.isPlus" равны true, но...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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