LINUX.ORG.RU
Ответ на: комментарий от anonymous

>а кнонть уже попробовал пересобрать gcc-4 самим gcc-4? Соберется ли ? :-)

AFAIK он так и собирается! Сначала сторонним компилятором, потом собой, потом тем что получилось после сборки собой. Потом сравнивает результаты (сборки собой не должны отличаться).

2vada: а что, стандарт С не предусматривает, какая операция должна первой выполниться? Поведение компилятора должно быть четко, *математически* определено в любой ситуации, и такой вот некорректный код наиболее просто описывает "любую ситуацию".

Гарантии, конечно, не дает, но как минимум четко видно, если что-то пошло не так.

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

Ну хотя да, это больше для спортивного интереса :))))

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

> Как кто, разработчики анекдотов конечно, undefined behavior их лучший друг !

Ну почему сразу undefined? с = с не есть lvalue, не так ли? Соответственно, c = c++ выполняется как c = (c++). По крайней мере, с точки зрения формальной логики должно быть 1 :-)

no-dashi ★★★★★
()
Ответ на: комментарий от lodin

> а что, стандарт С не предусматривает, какая операция должна первой выполниться?

Нет, не предусматривает.

> Поведение компилятора должно быть четко, *математически* определено в любой ситуации

Марш за парту!

anonymous
()

Ставил недавно Debian unstable amd64-gcc4 (собран на каком-то pre). Неделю был полет нормальный. Откатился на amd64-pure64 только из-за неразберих с зависимостями в репозитории. А так - вполне...

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

> ]cat 1.c #include <stdio.h>

> int main (void) { int c=0; ++c = c++; printf ("\n %d",c); return 1; }

> ]gcc -o 1 1.c 1.c: In function `main': 1.c:7: error: invalid lvalue in assignment

А VC6 считает, выдаёт 2 :-P

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

>Зачем тебе 4.1? Это же будет эксперементальная ветка?
С чего ты взял что у них значения номеров версий такое же как у ядра ???

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

>а кнонть уже попробовал пересобрать gcc-4 самим gcc-4? Соберется ли ?
А ты как думаешь ? Его первым делом и собираем им же, 4.0.0 правда я еще не собирал.

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

>По крайней мере, с точки зрения формальной логики должно быть 1 :-)

С точки зрения нормальной логики, не надо херней заниматься.

Для какого х### надо писать код, который и самому не понятен?

Что имелось ввиду в этой безумной строке?
c=c++;

Внятно можешь объяснтить? Или написано только для того шоб было?

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

>УЧИ МАТЧАСТЬ! c=++c, да один с=с++ НОЛЬ! И НИЧЕГО ДРУГОГО.

Эх, ты! Undefined behaviour, однозначно. Две модификации переменной (= и ++) не разделены точкой следования (присваивание - не является точкой следования). Я даже когда-то где-то ссылку на стандарт C99 давал и подробно объяснял, что и как.

Не читают фундаментальные труды, нет, не читают :)

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

>> УЧИ МАТЧАСТЬ! c=++c, да один с=с++ НОЛЬ! И НИЧЕГО ДРУГОГО.

c=++c это:
{
  c=c+1;
  c=c;
} итого 1

c=c++ это:
{
  c=c;
  c=c+1;
} итого тоже 1 :)

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

>>> УЧИ МАТЧАСТЬ! c=++c, да один с=с++ НОЛЬ! И НИЧЕГО ДРУГОГО.
>
>c=++c это:
>{
>  c=c+1;
>  c=c;
>} итого 1
>
>c=c++ это:
>{
>  c=c;
>  c=c+1;
>} итого тоже 1 :)

Лопух.
c=c++ :
{
 сохраняем c
 увеличиваем c на 1
 присваиваем c сохран. результат
} итого: 0

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

Аааа. Только не мой мозг. Сказали же, это UB. Повторяю: UB, unidefined behavior, по слогам не-оп-ре-де-лен-но-е по-ве-де-ние. Все эти выкладки полная и абслютная чушь.

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

Почему UB? Объясните доступно. Операнды = вычисляются раньше, чем выполняется присваивание. При вычислении левого оператора будет адрес в памяти, правого - число. Их значения не зависят от порядка вычисления. Разве не так?

anonymous
()

Не слушайте никого, сейчас придет Альфекс и все объяснит !

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

Пионерам бесполезно это объяснять, они всё равно ничему не учатся. Иди, перекомпилируй Gentoo с опцией -O9.

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

Никак комсомолец? Значок имеешь?

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

Когдато давно, когда сахар был слаще, а воробьи жирнее, в фидошной эхе с периодичностью 6 месяцев поднимался флейм по поводу GOTO.

Время прошло. Многое изменилось. Сахар стал не сладким, воробъи куда-то исчезли. Теперь всплывает пое###нь ++с=с++

Как достало! :(((((((((((((((((((((((

Пива бутылку
Ставлю назад в холодильник
Теплое сука.

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

В том, что на одном компе с одним компилятором это 1, а на другом 0, или что-то другое!

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

>>Зачем тебе 4.1? Это же будет эксперементальная ветка?

>С чего ты взял что у них значения номеров версий такое же как у ядра ???

А где ты увидел, что они как у ядра? Они не такие как у ядра. Текущие фиксы осуществляются в свежезарелизиной ветке, а для добавления новых фич открывают новую. Со временем, новая стабилизируется, и ее релизят не изменяя номера. Некоторое время она остается в качестве стабильной ветки и фиксы осуществляются в ней. Потом открывают новую, и т.д. 4.0.1 - будет фикс к 4.0, а 4.1 - пока ее официально не зарелизят (это произойдет никак не в течении месяца), будет экспериментальной.

alt-x ★★★★★
()
Ответ на: комментарий от clx

не стоит пересобирать , жди glibc-2.3.6

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

>>> УЧИ МАТЧАСТЬ! c=++c, да один с=с++ НОЛЬ! И НИЧЕГО ДРУГОГО.
>>
>>c=++c это:
>>{
>>  c=c+1;
>>  c=c;
>>} итого 1
>>
>>c=c++ это:
>>{
>>  c=c;
>>  c=c+1;
>>} итого тоже 1 :)

>Лопух.
>c=c++ :
>{
> сохраняем c
> увеличиваем c на 1
> присваиваем c сохран. результат
>} итого: 0

Ответил бы матом!!!

Посмотри, что тебе действительно выдаст код

На самом деле:
с=с++ выдаст 1.

Вот асмовский листинг:

; 3    : 	int c=0;

	mov	DWORD PTR _c$[ebp], 0

; 4    : 
; 5    : 	c=c++;

	mov	eax, DWORD PTR _c$[ebp]
	mov	DWORD PTR _c$[ebp], eax
	mov	ecx, DWORD PTR _c$[ebp]
	add	ecx, 1
	mov	DWORD PTR _c$[ebp], ecx

; 6    : }


работает оно так:
t1 = c;       // 
c = t1;       // c = c (но нужен промежуточный регистр)

t2 = c;       //
t2 = t2 + 1;  // c++ (без оптимизации тоже работаем в регистре)
c = t2;       // 

Пройдя стадию оптимизации:
t1 = c, c = t1 коситься нафик, остается c++

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

> остается c++

Никак нет. Все будет зависеть и от компилятора, и от оптимизатора: или постинкремент произойдет _до_ присвоения, или после. UB это. Курить стандарт языка.

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

> Операнды = вычисляются раньше, чем выполняется присваивание.

да, но это здесь не причем. в стандарте сказано, что ++ будет вычесленно
в следущем операнде, т.е. после ";". там оно будет на единицу больше,
а в самом выражении если ты в двух местах используешь
одну и ту же переменную и в одном месте ту ее используешь так: c++, то
не известно c будет увиличено сразу после или еще раз используется ее значение,
а только потом будет прибавление единицы

это в любой нормальной книжке по C написано.

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

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

>> остается c++

>Никак нет. Все будет зависеть и от компилятора, и от оптимизатора: или постинкремент произойдет _до_ присвоения, или после. UB это. Курить стандарт языка.

Еще и от проца\архитектуры зависит. На 86 свет клином не сошелся (типа то что неоптимизированый компилер наваял не догмат). А курить стандарт бестолку. Надо на толстом картоне распечатать и в туалет вместо туалетной бумаги. Пока мять будет глядишь прочитает :)

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

> Операнды = вычисляются раньше, чем выполняется присваивание.

Нет, там пост-инкрементация!

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

************************************************************* Оператор ++NC; демонстрирует новую операцию, ++, которая означает увеличе- ние на единицу. Вы могли бы написать NC = NC + 1 , но ++NC более кратко и зачастую более эффективно. Имеется соответст- вующая операция -- уменьшение на единицу. Операции ++ и -- могут быть либо префиксными (++NC), либо постфиксными (NC++); эти две формы, как будет показано в главе 2, имеют в выражениях различные значения, !но как ++NC, так и NC++ уве- личивают NC!.

Необычный аспект заключается в том, что ++ и -- можно использовать либо как префиксные операции (перед переменной, как в ++N), либо как постфиксные (после переменной: N++). Эффект в обоих случаях состоит в увеличении N. Но выражение ++N увеличивает переменную N до использования ее значения, в то время как N++ увеличивает переменную N после того, как ее значение было использовано. Это означает, что в контексте, где используется значение переменной, а не только эффект увеличения, использование ++N и N++ приводит к разным ре- зультатам. Если N = 5, то х = N++; устанавливает х равным 5, а х = ++N; полагает х равным 6. В обоих случаях N становится равным 6.

"ЯЗЫК С" Б.В. Керниган, Д.М. Ричи. *************************************************************

Ну хоть этим людям вы верите!?

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

>>Ну хоть этим людям вы верите!?

ипт ;) ну тебе же уже объяснили. други из массы, вы хоть бы если не знаете - попробовали на разных компилерах - отпустило бы сразу ;)

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

На gcc 3.3.5 будет 0:

monk@veles:~/test$ cat test.c 
int main()
{
        int c=0;
        c=c++;
        return c;
}
monk@veles:~/test$ gcc -S test.c 
monk@veles:~/test$ cat test.s
    .file   "test.c"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    movl    $0, -4(%ebp)
    movl    -4(%ebp), %edx
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    %edx, -4(%ebp)
    movl    -4(%ebp), %eax
    leave
    ret
    .size   main, .-main
    .section    .note.GNU-stack,"",@progbits
    .ident  "GCC: (GNU) 3.3.5 (Debian 1:3.3.5-8)"
monk@veles:~/test$ ./a.out; echo $?
0

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

> Какая разница в данной ситуации когда произойдет постинкремент. В любом случае будет 1.

Ты так и не понял. У нас _три_ действия:

1. Вычисление _значения_ выражения (i++), которое _всегда_ будет происходить первым (сначала вычисляется правая часть).
2. Присвоение переменной i _значения_, из (1.).
3. Инкремент переменной i (i+=1).

При этом (2.) и (3.) компилятор может расположить в любом порядке. В зависимости от ключей оптимизации, прилегающего кода и погоды на солнце.

То есть может быть как

t = i; // _значение_ (i++) _всегда_ равно i.
i = t;
i += 1;

так и

t = i;
i += 1;
i = t;

Возможный порядок действий и количество сочетаний для так любимого всеми

i += i+++++i;

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

PS. i = ++i; -- тоже UB.

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

>Хорошо, а в чем практическая полезность такого поведения? Что мы приобретаем за счет этого?

Ничего. Но это _стандарт_. Это последняя инстанция, разрешающая подобные религиозные споры. И она говорит, что поведение _не определено_. А значит программа - некорректна.

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

Ты учти, что x и N - различные переменные.

И вообще, не забывай, что последний стандарт был принят в 99 году, немного позже написания книги (хотя когда были введены точки следования - точно не скажу). Такие вопросы решает _только_ стандарт, книги нужны лишь для разъяснения и обучения.

WFrag ★★★★
()

Хватит спорить с разработчиками анекдотов, расскажите лучше о GCC 4.0 ! Как оно ?

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

Извиняюсь за несколько сумбурный пост. 4.0 - по мнению многих разработчиков, выпустили преждевременно, х.з. из каких соображенний. Туда слили не до конца доработаный и оттестированный оптимизатор из ветки 4.1. А осталось вроде совсем немного 8). Поэтому если доработка не затянется, то свет увидит раньше 4.1 нежели 4.0.1.

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

> ипт ;) ну тебе же уже объяснили. други из массы, вы хоть бы если не знаете - попробовали на разных компилерах - отпустило бы сразу ;)

Если цомпилер не реализует поведение, описанное стандартом, то это КРИВОЙ цомпилер, только и всего.

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

> На gcc 3.3.5 будет 0:

Значит, кривой компилер. Всё, finita la comedia.

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

> 1. Вычисление _значения_ выражения (i++), которое _всегда_ будет происходить первым (сначала вычисляется правая часть). 2. Присвоение переменной i _значения_, из (1.). 3. Инкремент переменной i (i+=1).

> При этом (2.) и (3.) компилятор может расположить в любом порядке. В зависимости от ключей оптимизации, прилегающего кода и погоды на солнце.

То, что он располагает их в произвольном порядке, - это его сексуальная проблема. То, что он при этом не получает ПРАВИЛЬНЫЙ ответ - это его ВИНА. Я, как программер на C, не обзязан вдаваться в подробности о том, насколько криво реализован сам компилер или оптимизация в нём. У меня есть книжка/стандарт, где чётко описано, что должно получиться. и ВСЁ. То, что компилер выдаёт что-то иное, не должно прикрываться фиговыми листочками типа "UB". ЭТО - БАГ, который никто не желает фиксить.

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

> Ничего. Но это _стандарт_. Это последняя инстанция, разрешающая подобные религиозные споры. И она говорит, что поведение _не определено_. А значит программа - некорректна.

Момент. Что, в изначальном стандарте языка C тоже фигурировало позорное "UB"? Или оно было добавлено много позже, чтобы тем самым злостно покрывать НЕВЕРНОЕ поведение некоторых компиляторов? Даааа уж, разработали язычок, мля.

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

>То, что он располагает их в произвольном порядке, - это его сексуальная проблема. То, что он при этом не получает ПРАВИЛЬНЫЙ ответ - это его ВИНА. Я, как программер на C, не обзязан вдаваться в подробности о том, насколько криво реализован сам компилер или оптимизация в нём. У меня есть книжка/стандарт, где чётко описано, что должно получиться. и ВСЁ. То, что компилер выдаёт что-то иное, не должно прикрываться фиговыми листочками типа "UB". ЭТО - БАГ, который никто не желает фиксить.

Лажу не пишите и все ок будет ;)

это из серии, давайте в стандарте опишем все самые идиотские варианты написания, какие токо может придумать извращенный мозг програмиста, которому нечем занятся!

>Необычный аспект заключается в том, что ++ и -- можно использовать либо как префиксные операции (перед переменной, как в ++N), либо как постфиксные (после переменной: N++). Эффект в обоих случаях состоит в увеличении N. Но выражение ++N увеличивает переменную N до использования ее значения, в то время как N++ увеличивает переменную N после того, как ее значение было использовано. Это означает, что в контексте, где используется значение переменной, а не только эффект увеличения, использование ++N и N++ приводит к разным ре- зультатам. Если N = 5, то х = N++; устанавливает х равным 5, а х = ++N; полагает х равным 6. В обоих случаях N становится равным 6.

тут сразу видно из описания UB, что делать если x=N? От момента присвоения зависит N=6 или N=5, и что должно происходит конкретно не описано. Пока в стандарте не будет написано что N этом варианте будет равно 6 или 5, все эти обсуждения просто переливание из пустого в порожнее.

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

>ЭТО - БАГ,

Если в стандарте сказано ub, то imho компилятор имеет право вести себя как угодно.

P.S. Лучше всего вывалиться с ошибкой ub, тогда кривого кода меньше будет.

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

> Лажу не пишите и все ок будет ;) это из серии, давайте в стандарте опишем все самые идиотские варианты написания, какие токо может придумать извращенный мозг програмиста, которому нечем занятся!

Хорошо продуманный язык тем и отличается, что лажу на нём написать сложно - поведение программы ОДНОЗНАЧНО и очевидно. А поведение "как бог на дущу положит" - это проблема языка, а не программиста. Это ПОЗОР для языка.

> тут сразу видно из описания UB, что делать если x=N? От момента присвоения зависит N=6 или N=5, и что должно происходит конкретно не описано. Пока в стандарте не будет написано что N этом варианте будет равно 6 или 5, все эти обсуждения просто переливание из пустого в порожнее.

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

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

> поведение программы ОДНОЗНАЧНО и очевидно

А оно и так однозначно и очевидно, если не использовать запрещенные конструкции. Или ты из той разновидности луддитов, которые ругают молоток за то, что им можно попасть по пальцам, а ружье за возможность выстрелить в ногу?

Если хочешь пользоваться инструментом, будь добр прочитать инструкцию. И _следовать_ ей. А по дурости можно и йцк сломать.

> Хорошо продуманный язык тем и отличается, что лажу на нём написать сложно

Вместо "сложно" ты хотел написать "невозможно"? Да, сейчас модно ругать С за наличие адресной арифметики, за неявное преобразование типов и т.д. Но С -- это всего-навсего "универсальный макро-ассемблер", один из самых низкоуровневых языков программирования высокого уровня. ;) И он уже не раз доказал эффективность в этом качестве.

Но если из С убрать адресную арифметику, ввести обязательную проверку границ и строгую типизацию, то получится Паскаль в своем первозданном виде.

> Это ПОЗОР для языка

Нет. Это позор для кодера. Клеймо профнепригодности для писателя "анекдотов на С" вида 'i=i++'.

> Язык плохо продуман

Язык хорошо продуман, просто некоторые не читают "инструкцию по эксплуатации".

Я еще в начале девяностых подсовывал студентам подобные задачки на дом, когда разбирали ЯВУ. Или общий уровень образованности сейчас упал, или просто каждый недоучка мнит себя специалистом, но тогда студенты в массе своей _сами_ доходили до понимания, что тут НП. Подходили со словами: "Вы, вероятно, ошиблись в задании: тут неоднозначность возникает". Нельзя в пределах одного оператора дважды присвоить значение переменной.

PS. Если отвлечься от НП, то "правильней" будет считать `i=i++` === `NOP`;

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

>Момент. Что, в изначальном стандарте языка C тоже фигурировало позорное "UB"?

Честно не знаю.

>Или оно было добавлено много позже, чтобы тем самым злостно покрывать НЕВЕРНОЕ поведение некоторых компиляторов? Даааа уж, разработали язычок, мля.

Что значит неверное? Конкретно точки следования были добавлены специально дабы позволить компилятору больший простор для оптимизации.

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

>Если цомпилер не реализует поведение, описанное стандартом, то это КРИВОЙ цомпилер, только и всего.

А он и реализует. UB может означать любое поведение.

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

http://www.digitalmars.com/d/dcompiler.html

может смотреть допустим в эту сторону и постепенно гнутую кривость послать подальше. быстрый C КОМПИЛЯТОР есть - tcc. собираются им программы нормально и быстро но c++ там нет.

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