С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/22: Рейтинг темы: голосов - 22, средняя оценка - 4.77
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
1

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

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

Author24 — интернет-сервис помощи студентам
Заметил такую странность:
Это проходит компиляцию
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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.10.2009, 00:31
Ответы с готовыми решениями:

БОМБА это кто нибудь может объяснить?
Взгляните на статичтику http://www.liveinternet.ru/stat/ru/searches.html Гугля обогнал рамблер...

Кто-нибудь может объяснить как это работает?
Именно создание списка не понятно main :: IO() main = do let fib = 0 : 1 : n <-...

может кто нибудь объяснить что это за цифры
дана программа может кто нибудь объяснить что это за цифры s:5:3 program proga7; uses crt; var...

действительно трудная задача может быть кто нибудь рискнет за это взяться
действительно трудная и стоящая задача но может быть кто нибудь рискнет за это взяться если кто...

26
125 / 123 / 0
Регистрация: 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
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
12.10.2009, 00:38  [ТС] 3
По идее false и NULL это не одно и тоже.Да и в C++ null не определён вроде,вот и спрашиваю.В-общем,мне как-то видится это нештатной ситуацией
0
125 / 123 / 0
Регистрация: 30.03.2009
Сообщений: 766
12.10.2009, 00:46 4
ну приводится же int к bool всегда, и все к этому привыкли уже, так почему бы и обратно не приводилось?
1
14 / 14 / 4
Регистрация: 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
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
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
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
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
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
11.12.2009, 15:47 8
> Чтобы никуда не указывать

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

Конкретное значение для NULL - зависит от платформы. Т.е. для всех "нормальных" платформ в качестве NULL выбирается ноль (и под такое значение настраивается макрос и компилятор). Для сигнальных процессоров выбирается другое значение.
1
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
11.12.2009, 15:49  [ТС] 9
Да,спасибо,я прочитал внимательнее твой пост
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
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
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
11.12.2009, 16:17  [ТС] 11
А ты на Багзилле в gcc зарегистрирован? Может,стоит написать им,чтобы компилятор хотя бы предупреждение выводил?
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
11.12.2009, 16:22 12
g++ всё делает согласно стандарту. Значение false эквивалентно нулю (что эквивалентно NULL), а потому такое присваивание можно делать без явного преобразования типа. А вот для true уже нельзя. Borland C++ работает ровно так же
1
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
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
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
04.11.2010, 23:25 14
#pragma, В Си действительно различны (ну как и говорил Evg, от архитектуры зависит).
В С++ его не рекомендуется использовать. Но определен он как #define NULL 0. Хотя не исключаю, что тоже может зависить от архитектуры
1
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
04.11.2010, 23:30  [ТС] 15
Хз,от чего это зависит,но select()-довольно часто используемая функция в linux.
про
C
1
#define NULL (void *)0
вроде уже писали.
Мне интересно,как они эти параметры сравнивают внутри select ..
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
04.11.2010, 23:58 16
Про select. Там не то, о чём ты пишешь. Про ноль говорится, что если ПОЛЯ структуры забить нулями. А про NULL - если вместо указателя на заполненную структуру подсунуть NULL
1
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
05.11.2010, 00:52 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 - нулевые указатели.» <Конец цитаты>
Видимо поэтому в новом стандарте предусмотрено специальное ключевое слово для обозначения пустого указателя.
0
57 / 57 / 5
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 02:27 18
В С++ NULL == 0 и компиляторов C++ для микропроцессоров не существует. Для Си есть, но там NULL хоть что-то значит. Однако в свежем стандарте С++, который готовится, будет таки специальная штука null, которая будет служить как раз для тех же целей что и NULL в Си.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
05.11.2010, 02:28 19
KpeHDeJIb, nullptr, а не null.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
05.11.2010, 03:05 20
Цитата Сообщение от KpeHDeJIb Посмотреть сообщение
В С++ NULL == 0
В стандарте этого нет. Там только сказано, что значение этого макроса зависит от реализации.
0
05.11.2010, 03:05
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.11.2010, 03:05
Помогаю со студенческими работами здесь

Кто объяснит почему true == false ?
Спасайте! а то я щас повешусь от взрыва мозга! Кто объяснит вот что это за фигня. Когда я в...

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

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

Что это? .MainFormOnTaskbar := True; Тут ошибка False не помог
begin Application.Initialize; Application.MainFormOnTaskbar := True; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
Как создать игру "Танчики" на Unity3d и C#
InfoMaster 14.01.2025
Разработка игр – это увлекательный процесс, сочетающий в себе творчество и технические навыки. В этой статье мы рассмотрим создание классической игры "Танчики" с использованием Unity3D и языка. . .
Организую платный онлайн микро-курс по доработке Android-клиента Telegram
_Ivana 14.01.2025
Официальная версия и распространенные форки не полностью устраивают? Сделай свою кастомную версию клиента! 4 занятия по 2 часа (2 недели пн, ср 19:00-21:00 по Москве). Первое вводное занятие. . .
Как создать приложение для фитнеса для iOS/iPhone на Kotlin
InfoMaster 14.01.2025
Создание собственного фитнес-приложения — это не только захватывающий, но и полезный процесс, ведь оно может стать вашим верным помощником на пути к здоровому и активному образу жизни. В современных. . .
Как создать приложение магазина для iOS/iPhone на Swift
InfoMaster 14.01.2025
Введение в разработку iOS-приложений Разработка приложений для iPhone и других устройств на базе iOS открывает огромные возможности для создания инновационных мобильных решений. В данной статье мы. . .
Это работает. Скорость асинхронной логики велика. Вопрос видимо останется в стабильности. Плата - огонь!
Hrethgir 13.01.2025
По прошлому проекту в Logisim Evolution https:/ / www. cyberforum. ru/ blogs/ 223907/ blog8781. html прилагаю файл архива проекта в Gowin Eda. Восьмибитный счётчик из сумматора+ генератор сигнала. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru