LINUX.ORG.RU

Си


2

4
#include <stdlib.h>
#include <stdio.h> 

int main(int argc, char *argv[]) {

char *num = «5555»; 	
	
	if (argc != 2) {
	printf(«No param\n»);
		exit(0);
	}
	
	if (argv[1] != num) {
	printf(«Fail num %s\n»,num);
	printf(«Fail arg %s\n»,argv[1]);
		exit(0);
	}

...
}

Подскажите, почему сравниваются два одинаковых значения, но определяются, как - неодинаковые!

Вывод программы:

Fail num 5555
Fail arg 5555

Ответ на: комментарий от geekless

Но стандарт указывает, что константа 0 это и есть null pointer constant в рамках языка.

ты тоже считаешь, что «в си нет никаких типов»? Константа 0 является целым числом, а вот константа NULL является указателем. Что-бы их сравнить, надо преобразовать тип. Так вот если преобразовать (void*)0, то получится NULL. Это никак не доказывает, что «NULL это 0». Это тоже самое, что сказать, что «метры это секунды», полный бред. И тем не менее, это не мешает мерить расстояния в годах. Надо только объяснить, что год «световой», и тогда всем будет понятно, что расстояние из лет получается после _перевода_.

emulek
()
Ответ на: комментарий от anonymous

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

ясно, спасибо за разъяснение.

emulek
()
Ответ на: комментарий от dvl36

Практически - очень сомневаюсь. 0 ведь выбран неспроста.

если сомневаешься, зачем пишешь (void*)0, а не просто 0? Это ведь одно и то же по твоему?

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

Я считаю, что тебе нужно резко научиться читать.

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

если сомневаешься, зачем пишешь (void*)0, а не просто 0? Это ведь одно и то же по твоему?

Это и есть одно и то же. Домашнее задание: найти страницу стандарта, на которой про это написано, прочитать и выучить.

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

Сишечка вот такой код int x = 7; int y = x-- - --x; на моей платформе считает эквивалентным коду int x = 5; int y = 0;, по той причине, что во первых такая трактовка допустима, а во вторых она самая быстрая и самая экономичная.

Трактовки бывают только у библий и коранов. То что разные компиляторы по разному трактуют этот код - проблема.

это проблема, но не проблема компилятора. Если у приказа есть разные трактовки, то приказ тупой, и выполнять его не нужно(хотя и можно, если хочется).

Для компилятора твой код == библия и коран. Твои слова для него святы. Если ты повелел делить на ноль, компилятор не отправит тебя в школу, а создаст код, который будет делить на ноль. Хороший компилятор может только что вякнуть замечанием, но код всё равно создаст. Ибо делить на ноль МОЖНО, если НУЖНО. Бох не ошибается. А ты и есть Бох, который придумывает правила для своего выдуманного бытия. И не дело компилятора обсуждать приказы. Что совсем не мешает ему в случае тупого приказа тупо ничего не делать.

emulek
()
Ответ на: комментарий от geekless

Это и есть одно и то же

это не одно и то же.

Домашнее задание: найти страницу стандарта, на которой про это написано, прочитать и выучить.

давай ты всё-же спросишь у кого-нибудь, кто умеет читать, как правильно понимать 7.17.3?

я процитирую, мне не тяжело:

The macros are NULL which expands to an implementation-defined null pointer constant;

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

сам неуч, у него проблема не в том, что он не знает функций работы со строками. а он языка не знает, то есть адресной арифметики, я ему наглядно объяснил. а если ему сунуть strcmp, что и было сделано в одном из первых постов, то языка он не узнает, а так хоть с адресной арифметикой может разберется.

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

что он не знает функций работы со строками. а он языка не знает, то есть адресной арифметики, я ему наглядно объяснил. а если ему сунуть strcmp

strcmp(3) это тоже часть языка. Причём в данном случае нужна именно ЭТА часть. И никакой адресной арифметики здесь быть не должно. Почитай остальные посты в этой теме, и ты убедишься, что адресной арифметикой вообще мало кто владеет хоть как-то. Иные считают, что NULL это 0, а иные считают, что типов вообще «нет», и указатели это такие «целые числа».

Посему оставь адресную арифметику на потом, для ТСа это ещё слишком сложно и не нужно. Ему сейчас будет проще считать сишные строки — сишными строками, которые надо сравнивать специальной функцией. А как он это усвоит, тогда и можно будет расковырять эти строки, и посмотреть, как они внутри реализованы. Тогда и дойдёт разговор до

int my_strcmp(const char *x, const char *y)
{
  while(*x && *y)
  {
    if(*x++ != *y++)
      return 1;
  }
  return 0;
}
И до разговора о том, почему strcmp(3) всё равно намного быстрее, и вообще 7.21.4.2 (:

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

Внезапно, мы обсуждаем стандарт, а не дырки в нем, то что ты тут вякнул про кривой стандарт Си (я не проверял, но таки тебе поверю) вообще ничего не значит, потому что это относится к undefined behavior. В случае с жабкой все четко оговорено в стандарте.

То есть твоя аналогия с Си - говно.

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

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

ну и gc

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

если уж зарываться то как Аксиома Null==Null (проективная геометрия) так и Аксиома Null!=Null (логика неизвестного) вполне полезны.

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

Стандарт стандартом а в gcc

#ifndef NULL
# if defined __GNUG__ && \
    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
#  define NULL (__null)
# else
#  if !defined(__cplusplus)
#   define NULL ((void*)0)
#  else
#   define NULL (0)
#  endif
# endif
#endif

blogdron
()
Ответ на: комментарий от dvl36

0 ведь выбран неспроста

вроде Хоар исполнял «плач ярославны» что это его решение использовать в качестве значения NULL двоичный ноль разползвшись по языкосоздателям принесла многомилиардные издержки.

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

одно и тоже в смысле символ 0 парсером воспринимается как NULL если ожидается указатель.

символ 0 не обязан быть значением 0 - вот вокруг этого вот «карта не есть територия» у вас диалог

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

Уже второй. Причем тут вообще java? На ней сравнивать ссылки в таком контексте тоже занятие бессмысленное.

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

я к тому что твой содискурсант не распарсивает твоё высказывание как различие имя именуемое , а всякий 0 читает как битовый 0 .

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

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

Вон вчера в треде про буферизацию IO, например, это чётко видно.

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

Внезапно, мы обсуждаем стандарт, а не дырки в нем, то что ты тут вякнул про кривой стандарт Си (я не проверял, но таки тебе поверю)

тут не кривость, а некоторая нелогичность стандарта. Если ты про то, что NULL==NULL. Это просто нужно знать. Ну как в русском «стеклянный, оловянный, деревянный». Нелогично, но что делать...

вообще ничего не значит, потому что это относится к undefined behavior.

Если ты не понял, то UB это НЕДОПУСТИМЫЙ ГОВНОКОД. Который выполняется ХРЕН ЗНАЕТ КАК. И оно ничего не доказывает, кроме квалификации говнокодера. Это в сишечке так.

Т.е. моё разъяснение про «работу» говнокода доказывает лишь то, что этого говнокода быть не должно. Как раз в силу того, что логике говнокод всё равно подчиняется, потому успешно проходит все тесты, и устраивает fuckup в продакшене.

В случае с жабкой все четко оговорено в стандарте.

ты невнимателен. Там как в сишечке «определено реализацией», т.е. хрен знает как(потому как ты не знаешь, с какими опциями твой юзер пожелает запускать твой код).

emulek
()
Ответ на: комментарий от qulinxao

проективная геометрия

мимо. NULL в сишечке это указатель, который никуда не указывает(т.е. по определению не существует объекта, на который указвывает NULL). Не путай пожалуйста это с недостижимым значением. Это твоё «недостижимое» может быть даже и существует, дело не в этом. Дело в том, что *NULL не существует по определению. Ну т.е. направить указатель на NULL ты можешь (как и умножить на ноль), а вот узнать, куда он направлен — не можешь(как разделить на ноль). Даже не можешь узнать, что один указатель который никуда не указывает указывает туда, куда и другой, который указывает тоже никуда. А вот в сишечке «никуда» существует, причём в единственном виде. Это несколько нелогично, хотя и удобно конечно.

emulek
()
Ответ на: комментарий от Kuzy
Integer number1 = 1;
Integer number2 = 1;
number1 == number2 //true

number1 и number2 указывают на один и тот же объект. Твой капитан.

anonymous
()
Ответ на: комментарий от qulinxao

символ 0 не обязан быть значением 0

кстати нет. По стандарту константа 0 имеет тип «целое». А вот целое число 0 просто обязано иметь все биты равными нулю. И да, если число не целое, то вообще говоря не обязан. В i8087 например ЕМНИП есть -0, который побитно отличается от +0, но они эквивалентны.

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

| Ты хоть можешь назвать платформу где это не так?

это не важно.

Это важно.

Ибо «Теория и практика иногда сталкиваются. Когда это случается, теория проигрывает. Всегда.» (C) L.Torvalds

dvl36
()
Ответ на: комментарий от qulinxao

решение использовать в качестве значения NULL двоичный ноль разползвшись по языкосоздателям принесла многомилиардные издержки.

Пускай не плачет, профита это принесло значительно больше.

dvl36
()
Ответ на: комментарий от qulinxao

символ 0 не обязан быть значением 0

В стандарте написано о значении:

An integer constant expression with the value 0
Я не нахожу здесь возможностей для разночтения.

dvl36
()
Ответ на: комментарий от Kuzy
Integer number1 = 1000;
Integer number2 = 1000;
number1 == number2 //true

number1 и number2 указывают на один и тот же объект.

anonymous
()
Ответ на: комментарий от dvl36

Ибо «Теория и практика иногда сталкиваются. Когда это случается, теория проигрывает. Всегда.» (C) L.Torvalds

всё верно. Ибо если в теории определено A, а на практике определено B, то истинна B, а теория неполная(если вообще не ошибочная).

Однако тут не сталкивается, в теории(в стандарте) значение NULL НЕ ОПРЕДЕЛЕНО. А то, что там нуль — твоя фантазия. По стандарту там не нуль, а результат преобразования нуля в (void*).

То, что на твоём локалхосте получается 0, это верно только для твоего локалхоста. Твоя теория может проиграть. И не важно, что пока она правильна на твоём локалхосте.

emulek
()

381 ответ

Да вы охренели, господа.

Deleted
()
Ответ на: комментарий от dvl36

понимаешь, если ты пишешь

#define NULL ((void*)0)
то это никак НЕ мешает тебе извлекать профит, например в таком коде
if(ptr == NULL)
на твоём локалхосте(и в наших продакшенах) NULL == 0, и компилятор сам это сократит и оптимизирует так, как будто-бы было написано ptr==0.

Профит в том, что в каких-то других продакшенах, с другим NULL(!=0), это тоже будет работать. А если ты напишешь просто ==0, то может сломаться.

emulek
()
Ответ на: комментарий от dvl36

An integer constant expression with the value 0 Я не нахожу здесь возможностей для разночтения.

тут и нет разночтений, тут сказано, что целое с содержимым 0 преобразуется в NULL, если преобразовывать.

А ниже сказано, что If the specified member is a bit-field, the behavior is undefined., что означает, что ежели попытаться посмотреть, какие же там получились битики, то получится фигня.

Что тебе до сих пор непонятно?

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

на твоём локалхосте(и в наших продакшенах) NULL == 0, и компилятор сам это сократит и оптимизирует так, как будто-бы было написано ptr==0.

Профит в том, что в каких-то других продакшенах, с другим NULL(!=0), это тоже будет работать. А если ты напишешь просто ==0, то может сломаться.

Не может.

http://c-faq.com/null/machnon0.html

Q: How should NULL be defined on a machine which uses a nonzero bit pattern as the internal representation of a null pointer?

A: The same as on any other machine: as 0 (or some version of 0; see question 5.4).

Whenever a programmer requests a null pointer, either by writing ``0" or ``NULL", it is the compiler's responsibility to generate whatever bit pattern the machine uses for that null pointer. (Again, the compiler can tell that an unadorned 0 requests a null pointer when the 0 is in a pointer context; see question 5.2.) Therefore, #defining NULL as 0 on a machine for which internal null pointers are nonzero is as valid as on any other: the compiler must always be able to generate the machine's correct null pointers in response to unadorned 0's seen in pointer contexts. A constant 0 is a null pointer constant; NULL is just a convenient name for it (see also question 5.13).

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

А то, что там нуль — твоя фантазия.

Это реальность. Хотя, как видно, ты от нее далек.

По стандарту там не нуль,

Цитирую снова:

An integer constant expression with the value 0,

 or such an expression cast to type void *, is called a null pointer constant.

а результат преобразования нуля в (void*).

«OR» значит «ИЛИ», доктор, «ИЛИ»!

dvl36
()
Ответ на: комментарий от AptGet

А если ты напишешь просто ==0, то может сломаться.

Не может.

в данном конкретном случае не сможет, т.к. перед сравнением 0 будет преобразован в NULL. Но в общем случае надо быть готовым к UB, если предоставить его как целое число без преобразование(например через union). Просто авторы этого FAQ'а не наступали на эти грабли.

ИМХО указатели вообще нельзя выпускать за пределы периметра локальной памяти. Да, даже NULL.

emulek
()
Ответ на: комментарий от dvl36

«OR» значит «ИЛИ», доктор, «ИЛИ»!

ох... начинаю понимать...

Тут фишка в том, что если компилятор ожидает указатель, то без разницы, что туда вставлять, 0 ИЛИ NULL. Эффект идентичный, и потому _в_ _данном_ случае 0 и NULL — синонимы.

Вот только это не всегда так.

Вот как тебе такой код:

int n = NULL;
здесь с обычным NULL хотя-бы замечание будет. А просто с 0 всё будет молча.

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

Вот, кстати, интересно, что по стандарту NULL может быть чем угодно (и, как пишут, даже когда-то так и было). Но теперь почему-то у всех NULL == (void*) 0;, даже на микроконтроллерах!

Неужто в стандарт уже можно писать, что NULL — нулевой указатель?

Anon
()
Ответ на: комментарий от geekless

а это(способность мыслить на нескольких уровнях абстракции) вообще и есть «способность мыслить»

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

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

в сишечке NULL это выделенное значение указателей который присваивается неразмещёным/неинециализированым_указуемым_значением.

обычно за NULL берётся невозможное для разименования значение.

впрочим бывали случаи в которых NULL было адресом умолчального значения.

несуществование по определению *NULL тоже удобное к использованию соглашение- вышеупомянутый Хоар ровно об этом и рыдал . что по причине ограничености NULL(в пределе лиш одно значение было NULL) возникла плохая ситуация когда NULL eq NULL вместо (NULL equal NULL)>(NULL eq NULL)

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

ну ....

прочитай всё таки стандарт ( в котором как раз строка «T* a= 0;» парсится в a=NULL вне зависимости какое/ие значение указателей этой платформы приняты за NULL)

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

там выражение . которое возвращает value 0 после приведения и размещения по месту хранения указателя не обязанно быть value 0 . т.е

int * a = 0; // NULL

if((int)a==0){
 Значит нам повезло и на этой платформе NULL есть набор нулевых битов)
}else{
 И такое стандарт допускает
}

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

Вот, кстати, интересно, что по стандарту NULL может быть чем угодно (и, как пишут, даже когда-то так и было). Но теперь почему-то у всех NULL == (void*) 0;, даже на микроконтроллерах!

хорош тупить. (void*)0 это МОЖЕТ БЫТЬ всё что угодно по стандарту. Например 666. И если посмотреть это побитно, то получаешь UB, по стандарту.

Пойми-ты наконец: Указатель НЕ число!

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