Ответить
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 15:59 Редактировалось Неизвестный кот, 1 раз.
    Mahagam:

    а ничего, что на некоторых платформах, по этому адресу мапится важная периферия или вообще - память.
    в досе там располагались вектора прерываний.а в msp430 там и сегодня находится регистр разрешения прерываний.в некоторых реализациях ARM7 с нуля начинается флеш (LPC2106 например).

    Ну вот опять. :(

    Например в упомянутой вами MS-DOS таблица прерываний находится по адресу 0000:0000. Из чего я делаю заключение что вы считаете что после выполнения
    int *foo = NULL;

    foo всегда будет равен нулю.

    НЕТ. Поскольку при присвоении NULL в foo может быть записан не 0, а например 0x12345678 если для данной архитектуры это определено.

    НКХЖЕХВ
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 16:05 Редактировалось Mahagam, 1 раз.

    gooblin, чот не понял что вы хотели сказать.
    ну и как можно что-то там сегфолтить при обращении по адресу 0 если вот

    To a C programmer strong typing means pressing the keys harder
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 16:09

    ладно, давайте поэтапно

    Mahagam:

    а ничего, что на некоторых платформах, по этому адресу мапится важная периферия или вообще - память.

    [1] по этому адресу это по какому? Напишите здесь пожалуйста его числовое значение: ___

    НКХЖЕХВ
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 16:17 Редактировалось Korben_Dallas, 8 раз(а).
    Mahagam:

    а напридумали они plus wraps round modulo the width of m. вернее - это не придумано ими,

    Это классно, но к языкам С и С++, как таковым, никакого отношения не имеет.

    Mahagam:

    это просто описано существующее поведение железа. большая часть т.н. стандарта - описание поведения железа.

    Ну тут вы вообще что-то выдумываете. По вашей же ссылке присутствуют несколько разных вариантов, в т.ч. варианты, которые не wrap around, а saturate на максимальном значении. Назовете мне пример железа, которое saturates вместо wrap around? :)

    А стандарт - это попытка учесть потребности очень разного железа, в том числе потенциального/воображаемого. До сих пор в стандартах С и С++ (C11 и C++17) мы видим формальную поддержку 1's-complement и signed magnitude платформ, хотя все реальное железо уже давно использует исключительно 2's complement.

    Mahagam:

    а ничего, что на некоторых платформах, по этому адресу мапится важная периферия или вообще - память.

    По какому "этому адресу"? :) Физическое значение нулевого указателя (null pointer value) на каждой платформе выбирается таким, чтобы "по этому адресу" не лежало ничего нужного. В этом вся идея.

    В большинстве реальных платформ физическое значение нулевого указателя выбивается равным `0`. Но если на некоторой платформе адрес `0` - это что-то нужное и полезное, то там в качестве физического значение нулевого указателя будет выбрано что-другое. `0xFFFFFFFF`, например, или что-то в этом роде.

    При этом null pointer constant (т.е. например макро NULL) переопределять не потребуется. На платформе с null pointer value = `0xFFFFFFFF` всякий раз, когда вы пишете

    код выделить все

    void *p = 0;

    if (p == 0)
    ...

    компилятор обязан распознать указательный контекст и странслировать данный код в занесение значения `0xFFFFFFFF` в `p` и сравнение значения `p` с `0xFFFFFFFF`(несмотря на то, что в тексте программы вы написали `0`).

    Mahagam:

    ну и как можно что-то там сегфолтить при обращении по адресу 0

    Это говорит о том, что вы не понимаете, как работает идея "null указателя" в языках С и С++ (и в том числе не поняли написанного по ссылке на comp.lang.c FAQ). Никакой привязки к адресу `0` null-указатель в С и С++ не имеет. Далее - см. выше.

    Et si tu tombes 7 fois Toujours se relever 8
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 16:19
    gooblin:

    Напишите здесь пожалуйста его числовое значение: ___

    0x00000000

    начиная с C++11 эту проблему (проблему понятия что есть nullptr) обошли. начиная с c++11 на тех платформах где надо - я могу смело писать int *foo = 0; *foo = any_value;
    в принципе, та я мог и раньше так писать, просто эта проверка на ноль могла сломать поведение корректной программы.

    Добавлено спустя 8 минут 58 секунд

    Korben_Dallas:

    компилятор обязан распознать указательный контекст

    ну зашибись, на платформе где nullptr != 0x0 обычно оно так, лишь потому, что по физическому адресу 0x0000 находится что-то полезное.
    а тут я пытаюсь добраться до этого полезного, а мне опля так - производят замену.

    ещё раз: в msp430 interrupt enable регистр имеет адрес 0x0000:
    #define IE 0x0000

    я правильно понимаю, что код
    int *p = IE;
    if (p == IE) *p = val;
    до регистра IE так и не доберётся??

    To a C programmer strong typing means pressing the keys harder
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 16:28 Редактировалось Неизвестный кот, 3 раз(а).

    Mahagam, почитайте что написал в своем последнем сообщении Korben_Dallas, - там все для вас понятно? вы со всем согласны?

    Добавлено спустя 10 минут 9 секунд

    Mahagam:

    ещё раз: в msp430 interrupt enable регистр имеет адрес 0x0000:#define IE 0x0000
    я правильно понимаю, что кодint *p = IE;if (p == IE) *p = val;до регистра IE так и не доберётся??

    Если для этой платформы физическое значение нулевого указателя (null pointer value) равно 0 то доберется, если нет то нет

    НКХЖЕХВ
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 16:42
    Korben_Dallas:

    Назовете мне пример железа, которое saturates вместо wrap around?

    если вы пишете не с телефона, а с x86/x64 машины - то оно так умеет. года эдак с 1996-го.
    в saturated вычисления умели и графические карты, до тех пор пока не перешли на шейдеры, там вопрос решился иначе.

    Korben_Dallas:

    Никакой привязки к адресу `0` null-указатель в С и С++ не имеет.

    с какого года? а как до этого писали программы в которых требовалось лазить в ноль?

    To a C programmer strong typing means pressing the keys harder
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 16:44 Редактировалось Korben_Dallas, 9 раз(а).
    Mahagam:

    с какого года?

    С появления первого стандарта языка С в 1989/1990 году. Хотя по-моему это поведение `0` в указательном контексте уже появилось в K&R - надо проверить. Во втором издании - точно, ибо оно подогнано под C89/90, а вот что там в первом - интересно было бы взглянуть.

    Кстати, я когда-то задавал именно этот вопрос на StackOverflow

    https://stackoverflow.com/questions/7128819/when-did-constant-0-i ... ial-status

    Согласно ответу Jerry Coffin, специальная обработка `0` в указательных контекстах появилась намного раньше.

    Mahagam:

    а как до этого писали программы в которых требовалось лазить в ноль?по физическому адресу 0x0000 находится что-то полезное.

    См. ниже.

    Mahagam:

    по физическому адресу 0x0000 находится что-то полезное.
    а тут я пытаюсь добраться до этого полезного, а мне опля так - производят замену.

    Это потому, что вы пытаетесь "добраться" до этого адреса совершенно криворуким и безграмотным способом. Откуда у вас в коде взялся `NULL`? `NULL` не предназначается и никогда не предназначался для доступа к адресу `0`. Оставьте `NULL` в покое.

    С формально-педантичной точки зрения, языки С и С++ не предоставляют портабельных способов добраться до конкретного адреса. Однако все мы понимаем, что в реальной жизни это может быть необходимо, по каковой причине как правило каждая реализация предоставляет средства для того, чтобы поставить указатель на конкретный адрес. Например, в С++ это обычно делается вот так

    int *p = reinterpret_cast<int *>(0xABCD1234);

    при этом в `reinterpret_cast` в С++ (в отличие от всех остальных кастов) не производит "подмены" для значения `0`, то есть даже на платформе с ненулевым null pointer value

    int *p = reinterpret_cast<int *>(0);

    должно занести в `p` физическое значение `0` и тем самым дать вам доступ к адресу `0` на вашей платформе.

    В С все несколько менее удобно, ибо там нет такого удобного `reinterpret_cast`. В С обычно

    int *p = (int *) 0xABCD1234;

    занесет вам конкретный адрес в указатель, но вот для константного значения `0` в указательном контексте всегда делается подмена. В том же самом comp.lang.c FAQ, который вы линковали, эта тема - обход подмены - отдельно освещена (http://c-faq.com/null/accessloc0.html). В частности, вы можете сделать

    int address = 0;
    int *p = (int *) address;

    и на типичной C платформе в `p` ляжет адрес `0`, как вы и хотели.

    Et si tu tombes 7 fois Toujours se relever 8
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 16:49

    Korben_Dallas, Mahagam, вообще поскольку этот вопрос implementation defined стопудово на конкретной платформе будет способ это сделать нормально

    1. вставка на ASM
    2. библиотечная функция доступа к памяти
    3. какое-либо нестандартное расширение языка типа "_at_"

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

    НКХЖЕХВ
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 16:50 Редактировалось Korben_Dallas, 1 раз.
    Mahagam:

    ещё раз: в msp430 interrupt enable регистр имеет адрес 0x0000:
    #define IE 0x0000

    я правильно понимаю, что код
    int *p = IE;
    if (p == IE) *p = val;
    до регистра IE так и не доберётся??

    Если на вашей платформе физическое значение null pointer value отличается от `0x0000`, то да, именно так. Это код не доберется до вашего регистра, ибо произойдет "подмена" константы `0x0000` на то самое физическое значение null pointer value.

    Добавлено спустя 2 минуты 8 секунд

    Mahagam:

    если вы пишете не с телефона, а с x86/x64 машины - то оно так умеет. года эдак с 1996-го.
    в saturated вычисления умели и графические карты, до тех пор пока не перешли на шейдеры, там вопрос решился иначе.

    Не надо напускать дыму про "умеет"/"не умеет". Покажите конкретно, как мне на x86/x64 получить знаковое целое, которое saturate вместо wrap around. Очень интересно.

    Et si tu tombes 7 fois Toujours se relever 8
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 17:07
    Korben_Dallas:

    Это код не доберется до вашего регистра

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

    Korben_Dallas:

    Покажите конкретно, как мне на x86/x64 получить знаковое целое, которое saturate вместо wrap around. Очень интересно.

    используй силу MMX/SSE, Люк! _mm_adds_epu8 - сложение, _mm_subs_epu8 - вычитание. всё с насыщением.

    я всё ещё хочу узнать, как в случае
    for (int i = 0; i>= 0; i++) {
    important_var = sqrt((double(i));
    ...
    }
    компилятор сделает и вечный цикл, и гарантирует мне корректность работы программы.

    To a C programmer strong typing means pressing the keys harder
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 17:28 Редактировалось Korben_Dallas, 4 раз(а).
    Mahagam:

    Korben_Dallas:

    Это код не доберется до вашего регистра

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

    Тут уже пошла какая-то демагогия. Вы изначально задали вопрос о том, что произойдет в компиляторе, который использует ненулевое null pointer value. Я вам да конкретный ответ. Теперь вы мне рассказываете, что "пользуетесь нормальными компиляторами"? Вы уж определитесь, о чем вы спрашиваете.

    Если в вашем "нормальном компиляторе" используется ненулевое null pointer value, но при этом не происходит трансляции нуля, то это не "нормальный компилятор", а потешная картонная дурилка, никакого отношения в языку С не имеющая. Но скорее всего, как обычно бывает в таких случаях, с компилятором-то все в порядке. Это вы сами просто чего-то навыдумывали.

    Mahagam:

    Korben_Dallas:

    Покажите конкретно, как мне на x86/x64 получить знаковое целое, которое saturate вместо wrap around. Очень интересно.

    используй силу MMX/SSE, Люк! _mm_adds_epu8 - сложение, _mm_subs_epu8 - вычитание. всё с насыщением.

    Это классно, но как вы сами понимаете, компиляторов С и С++ с насыщающимся `int` на горизонте не видно.

    Mahagam:

    я всё ещё хочу узнать, как в случае
    for (int i = 0; i&gt;= 0; i++) {
    important_var = sqrt((double(i));
    ...
    }
    компилятор сделает и вечный цикл,

    Я не понимаю вопроса. Компилятор сделает как угодно. Например, будет вечно итерировать с `i == 0`. Поведение не определено - этим все сказано.

    Отдельно надо заметить, что если ваш бесконечный цикл не обладает наблюдаемым поведением (observable behavior), то такой цикл сам по себе является дополнительным неопределенным поведением в С и С++. С и С++ не разрешают использования бесконечных циклов, не обладающих наблюдаемым поведением. GCC может такой цикл выбросить из программы вообще.

    Mahagam:

    и гарантирует мне корректность работы программы.

    У вашей программы и близко нет никакой "корректности работы". Вы эту корректность сами выдумали. А с точки зрения С и С++ поведение не определено.

    Смотрите сами: https://godbolt.org/g/XR6Gks - компилятор просто выкинул нафиг цикл.

    Et si tu tombes 7 fois Toujours se relever 8
  • stoGramm Senior Member
    офлайн
    stoGramm Senior Member

    3398

    16 лет на сайте
    пользователь #111145

    Профиль
    Написать сообщение

    3398
    # 12 марта 2018 17:31

    Народ, Вы запугали тех кто хочет начать карьеру айтишника.

  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 17:34
    Korben_Dallas:

    Смотрите сами: https://godbolt.org/g/XR6Gks - компилятор просто выкинул нафиг цикл.

    Справедливости ради - если убрать -O3 то все OK. Это побочные влияния оптимизации.

    Добавлено спустя 48 секунд

    stoGramm:

    Народ, Вы запугали тех кто хочет начать карьеру айтишника.

    :lol: я сам уже написать хотел что-то подобное.

    НКХЖЕХВ
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 17:40 Редактировалось Korben_Dallas, 3 раз(а).
    gooblin:

    Справедливости ради - если убрать -O3 то все OK. Это побочные влияния оптимизации.

    Разумеется. Но если "убрать -O3", то, извините, и "глухие начнут ходить, а хромые - говорить". Так у нас и пресловутое `i = i++ + i++` начнет "работать как ожидалось" :)

    В режиме -O3 компилятор GCC не пытается нарушать никаких требований стандарта языка. Наоборот, именно в режиме -O3 компилятор как раз в полной мере и пользуется свободой, предоставленной ему стандартом языка. Причем предоставленной именно для целей оптимизации кода.

    Et si tu tombes 7 fois Toujours se relever 8
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 17:49 Редактировалось Mahagam, 1 раз.
    Korben_Dallas:

    Если в вашем "нормальном компиляторе" используется ненулевое null pointer value, но при этом не происходит трансляции нуля, то это не "нормальный компилятор", а потешная картонная дурилка, никакого отношения в языку С не имеющая.

    оу, так как тогда быть с доступом к IE на MSP430. IE задано нулём производителем.
    да и другие случаи, когда по физическому нулю - что-то полезное.

    Korben_Dallas:

    компилятор просто выкинул нафиг цикл.

    нормальный ICC - всё сделал как надо.

    Korben_Dallas:

    компиляторов С и С++ с насыщающимся `int` на горизонте не видно.

    unsigned char a[16] __attribute__ ((aligned (16))) = { 200 };
    unsigned char b[16] __attribute__ ((aligned (16))) = { 70 };
    __m128i l = _mm_load_si128((__m128i*)a);
    __m128i r = _mm_load_si128((__m128i*)b);

    _mm_store_si128((__m128i*)a, _mm_adds_epu8(l, r));
    std::cout << (int)a[0] << std::endl;

    вполне себе компилится компиляторами си и си-крест-крест

    To a C programmer strong typing means pressing the keys harder
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 17:50
    Korben_Dallas:

    режиме -O3 компилятор GCC не пытается нарушать никаких требований стандарта языка. Наоборот, именно в режиме -O3 компилятор как раз в полной мере и пользуется свободой, предоставленной ему стандартом языка. Причем предоставленной именно для целей оптимизации кода.

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

    НКХЖЕХВ
  • Mahagam Senior Member
    офлайн
    Mahagam Senior Member

    4005

    17 лет на сайте
    пользователь #83779

    Профиль
    Написать сообщение

    4005
    # 12 марта 2018 17:53
    Korben_Dallas:

    пользуется свободой

    путая понятия "тип" и "число". отсюда и проблема

    To a C programmer strong typing means pressing the keys harder
  • Korben_Dallas Senior Member
    офлайн
    Korben_Dallas Senior Member

    2843

    13 лет на сайте
    пользователь #395360

    Профиль
    Написать сообщение

    2843
    # 12 марта 2018 17:54
    Mahagam:

    Korben_Dallas:

    Вы придумали свое поведение и почему-то решили, что оно - правильное.

    разберём пример

    код выделить все
    char *foo()
    {
    char hw[] = &quot;Hello World&quot;;
    return hw;
    }

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

    Нет, конечно. Поведение данного кода не определено. Это означает, в частности, что компилятор вообще может отказаться компилировать программу. Отказ от компиляции - легально допустимое проявление неопределенного поведения.

    Те шаги, которые вы описали - это поведение так называемой абстрактной С машины. Однако никто и никогда не требовал от компиляторов буквальной реализации реализации абстрактной С машины. Скомпилированная программа должно лишь повторять наблюдаемое поведение абстрактной С машины. Во всем остальном компиляторы могут делать что угодно и как угодно. Это - широко известное так называемое "правило as if".

    Данный кусок кода не обладает наблюдаемым поведением вообще, т.е. он никому ничего не должен.

    Mahagam:

    то, что адрес после выход будет не валидный, это уже компилятор не должно волновать. да, переменная hw была на стеке, да, после выхода их функции стек размотался и там уже не "Hello World". но кого это должно волновать? с какого перепугу компилятор выдумывает ноль?

    Это все - ваши личные домыслы. Стандартные языки С и С++ никогда не следовали такой логике.

    Mahagam:

    а если hw сделать const, так вообще пример должен корректно работать.

    В упор не вижу, как тут что-то может поменяться от `const`. Поясните.

    Et si tu tombes 7 fois Toujours se relever 8
  • Неизвестный кот Senior Member
    офлайн
    Неизвестный кот Senior Member

    12519

    21 год на сайте
    пользователь #6965

    Профиль

    12519
    # 12 марта 2018 17:58
    Korben_Dallas:

    В упор не вижу, как тут что-то может поменяться от `const`. Поясните.

    может он имел ввиду static?

    НКХЖЕХВ