LINUX.ORG.RU

И это мэйнстримный язык?

 , , ,


0

3

Имеем содержимое файла testbool.cpp

#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
    bool foo = 7 > 0;
    cout << foo << endl;
    bool bar = 7.5;
    cout << bar << endl;
    bool baz = "dont't foo";
    cout << baz << endl;
    return 0;
}
Компилируем:
den@haruhi:/tmp$ g++ -o testbool testbool.cpp
den@haruhi:/tmp$ ./testbool 
1
1

den@haruhi:/tmp$ g++ -Wall -o testbool testbool.cpp
den@haruhi:/tmp$ 

den@haruhi:/tmp$ g++ -std=c++0x -Wall -o testbool testbool.cpp
den@haruhi:/tmp$

Ничего, ни одного предупреждения несмотря на явное несоответствие типов.

Код на Java:

public class Main
{
    public static void main(String args[])
    {
        boolean foo = 7.5 < 0;
        System.out.println(foo);
        boolean baz = "Хурдыбурды";
        System.out.println(baz);
    }
}
Вывод компилятора:
den@haruhi:/tmp$ javac Main.java 
Main.java:7: incompatible types
found   : java.lang.String
required: boolean
		boolean baz = "Хурдыбурды";
		              ^
1 error

И как это понимать? Где «логический тип» в С++?

★★★★★

Последнее исправление: LongLiveUbuntu (всего исправлений: 1)
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
    bool foo = 7 > 0;
    cout << foo << endl;
    bool bar = 7.5;
    cout << bar << endl;
    bool baz = "dont't foo";
    cout << baz << endl;
    return 0;
}
den@haruhi:/tmp$ ./testbool 
1
1

Куда дели вывод baz?

AlexCones ★★★
()
Ответ на: комментарий от grondek

Потому что никто не гарантирует что отсутствие ошибок - это 0.

ыыы

в нормальном языке это гарантируется тем, что именно то, что автор указал конвертировать в true, в него и конвертируется

так было бы например в с++, если бы по причине «совместимости» с си не было бы кучи окольных путей сконвертнуть что-то в bool

особый цинизм ситуации придает то, что системные вызовы юникса именно 0 возвращают в случае успеха

Во втором случае комментарий не соответствует коду. У вас как раз и возвращается NULL в случае ошибки так то.

не чувак, ты вообще похоже ниче не понял — в случае ошибки возвращается строка с описанием ошибки, например «No route to host», в случае удачи — NULL

*естественно*, на нынешнем си это работать не будет, поскольку си сконвертит NULL в false

0xFFFFFFFF - это тоже true, как и любое отличное от 0 число.

а мозги включить?

вопрос в том, почему результат булевых операций true это 1, а не 0xFFFFFFFF

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)

И как это понимать? Где «логический тип» в С++?

ВНЕЗАПНО: нет, и никогда не было. Смирись.

drBatty ★★
()
Ответ на: комментарий от www_linux_org_ru

особый цинизм ситуации придает то, что системные вызовы юникса именно 0 возвращают в случае успеха

всё правильно делают. Ибо они возвращают _ошибку_. Если операция успешна, то очевидно error == false. Ну или 0.

не чувак, ты вообще похоже ниче не понял — в случае ошибки возвращается строка с описанием ошибки, например «No route to host», в случае удачи — NULL

возвращать в случае успеха NULL… Дядя, идите в конкурс непонятного программирования, призовое место ваше, за одну эту идею.

вопрос в том, почему результат булевых операций true это 1, а не 0xFFFFFFFF

идиотский вопрос. Какая разница, если это одно и то же? Просто в C/C++ понятие «булевых переменных» расширено, и имеется счётное множество(в идеале) true. А вот false только одно. AFAIK в старом стандарте, значение «истинно» было неопределённым. Т.е. 14==5 получалось 9.

drBatty ★★
()
Ответ на: комментарий от olegk

Если компилятор постоянно ругался бы, то получилось бы такое количество ругани в смешанных (C + С++) проектах, что просто на предупреждения перестали бы обращать внимание.

не думаю

если было бы можно компилировать сишные файлы компилятором си, а плюсовые — компилятором с++, и затем линковать, то все было бы ок

некоторая проблема была бы, если бы в си надо было писать

network_result_t r = do_something(....);
if( !r ){ 
  printf("all ok\n");

а в с++ можно было бы написать

#pragma convert_enum_0_to_bool_true
...
...
...
...
network_result_t r = do_something(....);
if( r ){ 
  printf("all ok\n");

и это только в том случае, когда код тупо копипастился из си, а не транслировался из си в с++ — в случае копипаста он мог бы втихую приобрести баги

короче, идея *синтаксической* совместимости со старьем — ужасна

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 4)
Ответ на: комментарий от LongLiveUbuntu

в силу традиции

интересно, почему тогда игнорируется 200-летняя традиция перегрузки математических операторов?

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от drBatty

Если операция успешна, то очевидно error == false. Ну или 0.

очевидно тому, кто страдает си головного мозга

а нормальным людям очевидно, что успех всегда только один, а неудач много (поскольку в случае неудачи нас живо интересует ее конкретная причина, которых всегда потенциально много) — поэтому успех это 0, а неудача — все остальное

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от nanoolinux
Derived array[10];
Base* ptr = &array[3];
++ptr;

емнип в си тоже есть че-то похожее, если в конце структуры разместить массив неопределенной длинны... или это гнутое расширение — кто подскажет?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от AlexCones

я его потом дописал, скомпилировал, но не запустил заново

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

а нормальным людям очевидно, что успех всегда только один, а неудач много (поскольку в случае неудачи нас живо интересует ее конкретная причина, которых всегда потенциально много) — поэтому успех это 0, а неудача — все остальное

вообще-то твоё рассуждение эквивалентно следующему:

бла-бла-бла — поэтому успех это -14, а неудача — все остальное

И вообще, понятия «успех», «неудача», «секс» и так далее можно обозначать как угодно, т.е. произвольно (тройка, семёрка, дама например).

Совсем иное дело код ошибки. Он должен быть истинным если ошибка была, и ложным, если ошибки не было. Именно так и воспринимается то, что _возвращает_ функция main() или программа в Windows|Linux|MacOS.

А ты просто не с того конца подошёл к какашке. Что-бы понять её суть, посмотри на жопу, а не думай о питательности.

drBatty ★★
()
Ответ на: комментарий от www_linux_org_ru

если в конце структуры разместить массив неопределенной длинны...

это быдлокод, за который надо убивать.

drBatty ★★
()
Ответ на: комментарий от drBatty

И вообще, понятия «успех», «неудача», «секс» и так далее можно обозначать как угодно, т.е. произвольно (тройка, семёрка, дама например).

чувак, ты совсем под веществами?

вот тебе конкретная задача: функция f(char* username) должна найти в домашнем каталоге пользователя username конфиг проги coolprog (т.е. обычно это /home/$username/.coolprog) и заменить строку start=yes на start=no; если же такого конфига нет, то его следует создать и вписать туда одну такую строку

придумай, что должна возвращать функция

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

функция f(char* username) должна найти в домашнем каталоге пользователя username конфиг проги coolprog (т.е. обычно это /home/$username/.coolprog) и заменить строку start=yes на start=no; если же такого конфига нет, то его следует создать и вписать туда одну такую строку

придумай, что должна возвращать функция

что-бы узнать, что должна возвращать функция, я должен знать о её окружении, а вовсе не о её реализации.

Ты задал вопрос, вроде такого: «работник должен войти в помещение Z и передвинуть предмет W из точки S в точку D. Если в Z нету W, то работник должен его найти и принести. Вопрос: что должен сказать своей жене работник, после выполнения задания?»

ЗЫЖ второй вопрос риторический: не лучше-ли бы тебе перейти на более лёгкие наркотики, вроде анаши?

drBatty ★★
()
Ответ на: комментарий от www_linux_org_ru

ну да, если ее напишет dr.batty, то будет скорее всего так

у меня они void обычно. В данном случае функция ничего не должна возвращать. А если и должна, то не туда, откуда её вызывают. Потому как то окружение, что вызвало функцию, всё равно не сможет обработать ошибку. А кроме ошибок/успеха, иных исходов нет.

drBatty ★★
()
Ответ на: комментарий от drBatty

Ты задал вопрос, вроде такого: «работник должен войти в помещение Z и передвинуть предмет W из точки S в точку D. Если в Z нету W, то работник должен его найти и принести. Вопрос: что должен сказать своей жене работник, после выполнения задания?»

facepalm.jpg

не жене, а начальнику

и сказать он может «помещение Z закрыто, войти не могу, дайте ключ что-ли?», «предмет W оказался слишком тяжелым», «предмет W прикручен болтом на ..., дайте ключ на ...», ... или просто «все сделал, шеф»

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от drBatty

А кроме ошибок/успеха, иных исходов нет.

так, это уже прогресс, позволяющий надеятся на наличие у тебя головного мозга — ведь раньше среди исходов упоминался еще и «секс»

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от drBatty

что-бы узнать, что должна возвращать функция, я должен знать о её окружении, а вовсе не о её реализации.

и я тебе специально задал функцию с известным окружением... или ты хочешь сказать, что нихрена не знаешь про работу с файлами типа /home/$user/.coolprog ?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

не жене, а начальнику

в том-то и дело, что родной и близкой жене, а не начальнику, который хрен знает где. Программа вызывает функцию работая как «жена», а её внутренняя логика мало относится к вызывающей части (может и вообще быть неизвестной, и даже заведомо неизвестной, как чистая виртуальная функция).

и сказать он может «помещение Z закрыто, войти не могу, дайте ключ что-ли?», «предмет W оказался слишком тяжелым», «предмет W прикручен болтом на ..., дайте ключ на ...», ... или просто «все сделал, шеф»

тут как раз ситуация такая, что жена мужа посылает на работу, хавчик ему собирает и т.д. А начальник давно инструкцию дал, много лет назад. Он не может и не должен вдаваться в рабочие ситуации, ему проще самому сдвинуть W, чем что-то объяснять слабаку. Ну и жена тоже не в состоянии ничем помочь, когда муж будет жаловаться на тяжесть W.

Возвращаясь к твоему примеру: подумай сам, какая разница вызывающему коду до того, что конфиг недоступен для записи? Это проблемы функции, а не кода. Если проблема настолько глобальная, что требует закрытия всего производства, то рапортовать надо не жене и не друзьям, а по инстанциям на самый верх. Т.е. использовать исключения.

drBatty ★★
()
Ответ на: комментарий от drBatty

что-бы узнать, что должна возвращать функция, я должен знать о её окружении, а вовсе не о её реализации.

а если ты под «окружением функции» подразумеваешь программный код, то спешу тебя обрадовать — ты скорее всего пишешь говнокод, т.к. функция должна выполнять свою задачу, ничего не зная об окружающем коде

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

так, это уже прогресс, позволяющий надеятся на наличие у тебя головного мозга — ведь раньше среди исходов упоминался еще и «секс»

нет. В данном случае и секс можно тоже ввернуть, просто лень. Проблема в том, что тому, кто вызывал функцию f(), плевать на результат. Вызывающий всё равно ничего не сможет сделать в случае провала(и секса).

drBatty ★★
()
Ответ на: комментарий от drBatty

Т.е. использовать исключения.

у пациента наблюдаются проблески сознания

я не против исключений, но речь идет о чистом си — и любое исключение можно, хотя и несколько геморно, изобразить с помощью кодов возврата

вот и изобрази

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

и я тебе специально задал функцию с известным окружением...

нет. Про окружение f() ничего неизвестно.

или ты хочешь сказать, что нихрена не знаешь про работу с файлами типа /home/$user/.coolprog ?

а причём тут работа с f()? Саму функцию я напишу, а что она должна возвращать — я не знаю. Кому возвращать и зачем?

drBatty ★★
()
Ответ на: комментарий от www_linux_org_ru

а если ты под «окружением функции» подразумеваешь программный код, то спешу тебя обрадовать — ты скорее всего пишешь говнокод, т.к. функция должна выполнять свою задачу, ничего не зная об окружающем коде

а ты меня не спрашивал о выполнении, ты спрашивал о возвращаемом значении. Или оно тоже зависит только от внутренностей? Ты испражняешься тоже тогда, когда прямая кишка заполнится, вне зависимости от окружения? ☺

drBatty ★★
()
Ответ на: комментарий от drBatty

Вызывающий всё равно ничего не сможет сделать в случае провала

откуда ты взял этот бред?

в случае провала можно показать мессаджбокс юзеру, либо записать в лог, либо попробовать снова через несколько секунд, либо ...

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от drBatty

Саму функцию я напишу, а что она должна возвращать — я не знаю.

напиши функцию на псевдокоде русскими/английскими словами, тогда наверно поймешь

до этого с тобой говорить бесполезно

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

я не против исключений, но речь идет о чистом си — и любое исключение можно, хотя и несколько геморно, изобразить с помощью кодов возврата

кодов возврата тут недостаточно. Проблема в том, что возможно два исхода, а значит и нужна возможность вернуть два набора кодов возврата. Можно предложить например такую систему:

0 — успех

100 — не удалось создать временный файл

101 — не удалось записать во временный файл

102 — не закрыть временный файл

103 — не удалось заменить конфиг новым(временным файлом)

104 — не удалось открыть конфиг для чтения

при такой реализации случай отсутствия конфига не требует особой логики, кроме как внутренней ошибки ENOENT, которая в случае старого конфига(104) не ошибка, а норма.

Очевидно, что эти ошибки будут часто встречаться и в других частях программы, а не только там, где вызывается f(). Потому этому коду надо просто отдать выше код возврата.

drBatty ★★
()
Ответ на: комментарий от drBatty

0 — успех ... 104 — не удалось открыть конфиг для чтения

ну наконец, после кучи бессмысленных постов, ты все же включил мозги

да, возможен такой вариант, возможен еще скажем вариант а-ля http/ftp, т.е. char* у которого в начале число, «104 can not open config file for reading» — мне он нравится больше, но это не важно

важно что неудач много, а успех — один

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

важно что неудач много, а успех — один

ты так ничего и не понял: для кода, который вызывает f() нет никакой разницы, какой результат f(). Если это даже полный провал, то коду ничего не остаётся, как отдать код провала уровнем выше. Если ты желаешь что-то там в лог писать, то это нужно делать либо в контексте main(), либо в контексте f(), но никак не посередине.

Если ты не желаешь делать исключения try-catch, то у тебя один путь: делать их эмуляцию, возвращая из функции «bool» (т.е. два любых значения, не важно каких), и если провал, то выходить вверх.

Ну то, что «неудач много, успех один» в общем случае неверно. Например f() может выполнится успешно, а может выполнится успешно, но при этом конфиг она изменить не сможет. Но по твоей логике это тоже «успех», ибо этот конфиг возможно находится на read only разделе, и менять его потому нет смысла. В общем случае нужно какой-то объект состояния, который не получится запаковать в int, и который вовсе не обязан быть целым кодом. Ну и даже если он и целый, то часто его неудобно передавать как код возврата (man 3 errno).

возможен еще скажем вариант а-ля http/ftp, т.е. char* у которого в начале число, «104 can not open config file for reading» — мне он нравится больше, но это не важно

а мне такой вариант совсем не нравится, ибо ты заковырял структуру в текстовую строку. Это уже потенциальная дыра, которая к тому-же сложно обнаружима, ибо на этапе тестирования ошибки редко выскакивают. А вот при эксплуатации оно выстрелит, когда ты начнёшь парсить «105 0», и ВНЕЗАПНО выяснится, что парсится у тебя последний эл-т, и ошибка у тебя воспринимается как «успех». Таких ошибок можно избежать, если вместо структуры использовать структуру. Тогда никакого парсинга и не нужно.

drBatty ★★
()
Ответ на: комментарий от www_linux_org_ru

откуда ты взял этот бред?

в случае провала можно показать мессаджбокс юзеру, либо записать в лог, либо попробовать снова через несколько секунд, либо ...

это всё надо делать не тому, кто f() вызвал, а самой f(), если она скажем не смогла открыть конфиг(т.е. он есть, но не открывается, ибо EROFS). Вызывающий f() вообще не в курсе про конфиг и про его EROFS, потому и не сможет обработать ошибку.

drBatty ★★
()
Ответ на: комментарий от LongLiveUbuntu

Так бы и написал что единица потерялась когда разделял строки команд для лора :D

bhfq ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

очевидно тому, кто страдает си головного мозга

сюрприз: досовые/вендовые bat скрипты возвращают тоже error. есть даже специальная переменная ERRORLEVEL, содержащая код возврата. rtfm :)

http://ss64.com/nt/errorlevel.html

The exit codes that are set will vary according to the application/utility, in general a code of 0 (false) will indicate successful completion.

invy ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

у http/ftp/smtp/и т.п. нет никаких текстовых строк, только код возврата. все текстовые строки - это только для удобства пользователя.

invy ★★★★★
()
Ответ на: комментарий от invy

у http/ftp/smtp/и т.п. нет никаких текстовых строк, только код возврата. все текстовые строки - это только для удобства пользователя.

В http код возвращается строкой. В smtp тоже. Да, пояснения опциональны.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

То, как он передаётся, - дело десятое. Та часть, программы, которая анализирует код ошибки, работает уже с числом.

invy ★★★★★
()
Ответ на: комментарий от invy

Та часть, программы, которая анализирует код ошибки, работает уже с числом.

Все программы работают с числами.

i-rinat ★★★★★
()
Ответ на: комментарий от invy

в контексте этого сообщения?

Я не улавливаю суть, поэтому поясню, как это видится с моей стороны.

Меня зацепила фраза о том, что HTTP возвращает результат числом, в то время как там строка, в которой в ASCII кодировке записано число. Для меня это разные вещи, поэтому я не поленился написать сообщение о этом. Потом меня зацепила фраза, что программа обрабатывает HTTP ответ в виде числа. (Когда я писал свой микро-прокси, сравнивал их как строки. Так было проще). Но ведь если подумать, то компьютер обрабатывает не символы, а числа, их кодирующие. Так что да, та часть программы, как и любая другая, работает с ответом как с числом. Dixi.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Все программы работают с числами.

часто числа это символы.

drBatty ★★
()

Ничего, ни одного предупреждения несмотря на явное несоответствие типов.

Тебя напрягает, что компилятор работает в соответствии со спеком, которого ты не знаешь, то, что спеки с++ отличаются от спеков жабы, или что?

И как это понимать? Где «логический тип» в С++?

Жуткий боянэ. Введи в любимый поисковик «safe bool» и удивись.

auto12884839
()
Ответ на: комментарий от bvn13

Ничего страшного. Когда чего-то не хватает, есть смысл остановиться и подумать - а туда ли ты вообще идешь? и тогда ВНЕЗАПНО авяснится, что такое поведение Си не только не нужно, но и вредно.

d_Artagnan ★★
()
Ответ на: комментарий от www_linux_org_ru

не чувак, ты вообще похоже ниче не понял — в случае ошибки возвращается строка с описанием ошибки, например «No route to host», в случае удачи — NULL

*естественно*, на нынешнем си это работать не будет, поскольку си сконвертит NULL в false

Вот я и говорю, что код не соответствует комментарию, потому что при возврате NULL выполнится то что в else.

И не в «нынешнем c», а в c и c++ вообще, потому что никто не будет ломать совместимость.

вопрос в том, почему результат булевых операций true это 1, а не 0xFFFFFFFF

А зачем результат булевых операций сравнивать с int'ом? Я честно говоря не помню, что там в спецификации, но это не совсем корректно, сравнивать true и int(1).

grondek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.