* [devel] вопрос по языку Си - порядок вычисления операндов
@ 2009-10-01 1:24 Alexey Tourbin
2009-10-01 5:00 ` Damir Shayhutdinov
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Alexey Tourbin @ 2009-10-01 1:24 UTC (permalink / raw)
To: devel
[-- Attachment #1: Type: text/plain, Size: 4217 bytes --]
У нас в rpm есть такой код.
lib/depends.h:
108 typedef /*@abstract@*/ struct availableList_s {
109 /*@owned@*/ /*@null@*/ struct availablePackage * list; /*!< Set of packages. */
110 struct availableIndex index; /*!< Set of available items. */
111 int delta; /*!< Delta for pkg list reallocation. */
112 int size; /*!< No. of pkgs in list. */
113 int alloced; /*!< No. of pkgs allocated for list. */
114 int numDirs; /*!< No. of directories. */
115 /*@owned@*/ /*@null@*/ dirInfo dirs; /*!< Set of directories. */
116 } * availableList;
...
lib/depends.c:
213 static /*@exposed@*/ struct availablePackage *
214 alAddPackage(availableList al,
215 Header h, /*@null@*/ /*@dependent@*/ const void * key,
216 /*@null@*/ FD_t fd, /*@null@*/ rpmRelocation * relocs)
217 /*@modifies al, h @*/
218 {
219 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
220 HFD_t hfd = headerFreeData;
221 rpmTagType dnt, bnt;
222 struct availablePackage * p;
223 rpmRelocation * r;
224 int i;
225 int_32 * dirIndexes;
226 const char ** dirNames;
227 int numDirs, dirNum;
228 int * dirMapping;
229 struct dirInfo_s dirNeedle;
230 dirInfo dirMatch;
231 int first, last, fileNum;
232 int origNumDirs;
233 int pkgNum;
234
235 if (al->size == al->alloced) {
236 al->alloced += al->delta;
237 al->list = xrealloc(al->list, sizeof(*al->list) * al->alloced);
238 }
...
703 int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
704 const void * key, int upgrade, rpmRelocation * relocs)
705 {
706 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
707 HFD_t hfd = headerFreeData;
708 rpmTagType ont, ovt;
709 /* this is an install followed by uninstalls */
710 const char * name;
711 int count;
712 const char ** obsoletes;
713 int alNum;
714
715 /*
716 * FIXME: handling upgrades like this is *almost* okay. It doesn't
717 * check to make sure we're upgrading to a newer version, and it
718 * makes it difficult to generate a return code based on the number of
719 * packages which failed.
720 */
721 if (ts->orderCount == ts->orderAlloced) {
722 ts->orderAlloced += ts->delta;
723 ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
724 }
725 ts->order[ts->orderCount].type = TR_ADDED;
726 if (ts->addedPackages.list == NULL)
727 return 0;
728
729 alNum = alAddPackage(&ts->addedPackages, h, key, fd, relocs) -
730 ts->addedPackages.list;
731 ts->order[ts->orderCount++].u.addedIndex = alNum;
...
Вопрос касается строк 729-730. Следите за движением рук.
ts->addedPackages -- это некоторая структура данных, которая содержит
ts->addedPackages.list -- указатель на массив, выделяемый в куче.
Функция alAddPackage() добавляет новый элемент в этот массив и возвращает
на него указатель. Соответственно (по правилам типизированной адресной
арифметики) переменная alNum -- это будет индекс последнего добавленного
элемента в массиве.
Но! Когда массив становится слишком маленьким, функция alAddPackage()
делает realloc этого массива (строка 237). Соотвественно, адрес массива
ts->addedPackages.list может измениться.
Теперь посмотрим на вычитание указателей в строках 729-730. Левый
операнд вычитания может изменить ts->addedPackages.list, а правым
операндом является сам ts->addedPackages.list. Получается, что этот
код зависит от порядка вычисления операндов -- а именно, может
использоваться либо старое значение ts->addedPackages.list, либо
уже новое значение.
Воопрос соответствено насколько легален этот код, и вообще любая
нетривиальная информация на эту тему.
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 1:24 [devel] вопрос по языку Си - порядок вычисления операндов Alexey Tourbin
@ 2009-10-01 5:00 ` Damir Shayhutdinov
2009-10-01 5:02 ` Kirill A. Shutemov
2009-10-01 8:31 ` Kharitonov A. Dmitry
2 siblings, 0 replies; 13+ messages in thread
From: Damir Shayhutdinov @ 2009-10-01 5:00 UTC (permalink / raw)
To: ALT Linux Team development discussions
> Теперь посмотрим на вычитание указателей в строках 729-730. Левый
> операнд вычитания может изменить ts->addedPackages.list, а правым
> операндом является сам ts->addedPackages.list. Получается, что этот
> код зависит от порядка вычисления операндов -- а именно, может
> использоваться либо старое значение ts->addedPackages.list, либо
> уже новое значение.
>
> Воопрос соответствено насколько легален этот код, и вообще любая
> нетривиальная информация на эту тему.
Сделал тест:
#include <stdio.h>
static int change(int* p)
{
*p = *p + 1;
return *p;
}
void main(void)
{
int a = 100;
int b = change(&a) - a;
printf("a=%d, b=%d\n", a, b);
}
После компиляции и запуска получается что b = 0; Что с -O0, что с -O2,
что с -O3.
Под рукой нет стандарта С, чтобы уточнить, но по крайней мере для gcc
этот код, похоже, легален.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 1:24 [devel] вопрос по языку Си - порядок вычисления операндов Alexey Tourbin
2009-10-01 5:00 ` Damir Shayhutdinov
@ 2009-10-01 5:02 ` Kirill A. Shutemov
2009-10-01 5:09 ` Kirill A. Shutemov
2009-10-01 8:31 ` Kharitonov A. Dmitry
2 siblings, 1 reply; 13+ messages in thread
From: Kirill A. Shutemov @ 2009-10-01 5:02 UTC (permalink / raw)
To: ALT Linux Team development discussions
2009/10/1 Alexey Tourbin <at@altlinux.ru>:
> У нас в rpm есть такой код.
>
> lib/depends.h:
> 108 typedef /*@abstract@*/ struct availableList_s {
> 109 /*@owned@*/ /*@null@*/ struct availablePackage * list; /*!< Set of packages. */
> 110 struct availableIndex index; /*!< Set of available items. */
> 111 int delta; /*!< Delta for pkg list reallocation. */
> 112 int size; /*!< No. of pkgs in list. */
> 113 int alloced; /*!< No. of pkgs allocated for list. */
> 114 int numDirs; /*!< No. of directories. */
> 115 /*@owned@*/ /*@null@*/ dirInfo dirs; /*!< Set of directories. */
> 116 } * availableList;
> ...
>
> lib/depends.c:
> 213 static /*@exposed@*/ struct availablePackage *
> 214 alAddPackage(availableList al,
> 215 Header h, /*@null@*/ /*@dependent@*/ const void * key,
> 216 /*@null@*/ FD_t fd, /*@null@*/ rpmRelocation * relocs)
> 217 /*@modifies al, h @*/
> 218 {
> 219 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
> 220 HFD_t hfd = headerFreeData;
> 221 rpmTagType dnt, bnt;
> 222 struct availablePackage * p;
> 223 rpmRelocation * r;
> 224 int i;
> 225 int_32 * dirIndexes;
> 226 const char ** dirNames;
> 227 int numDirs, dirNum;
> 228 int * dirMapping;
> 229 struct dirInfo_s dirNeedle;
> 230 dirInfo dirMatch;
> 231 int first, last, fileNum;
> 232 int origNumDirs;
> 233 int pkgNum;
> 234
> 235 if (al->size == al->alloced) {
> 236 al->alloced += al->delta;
> 237 al->list = xrealloc(al->list, sizeof(*al->list) * al->alloced);
> 238 }
> ...
> 703 int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
> 704 const void * key, int upgrade, rpmRelocation * relocs)
> 705 {
> 706 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
> 707 HFD_t hfd = headerFreeData;
> 708 rpmTagType ont, ovt;
> 709 /* this is an install followed by uninstalls */
> 710 const char * name;
> 711 int count;
> 712 const char ** obsoletes;
> 713 int alNum;
> 714
> 715 /*
> 716 * FIXME: handling upgrades like this is *almost* okay. It doesn't
> 717 * check to make sure we're upgrading to a newer version, and it
> 718 * makes it difficult to generate a return code based on the number of
> 719 * packages which failed.
> 720 */
> 721 if (ts->orderCount == ts->orderAlloced) {
> 722 ts->orderAlloced += ts->delta;
> 723 ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
> 724 }
> 725 ts->order[ts->orderCount].type = TR_ADDED;
> 726 if (ts->addedPackages.list == NULL)
> 727 return 0;
> 728
> 729 alNum = alAddPackage(&ts->addedPackages, h, key, fd, relocs) -
> 730 ts->addedPackages.list;
> 731 ts->order[ts->orderCount++].u.addedIndex = alNum;
> ...
>
> Вопрос касается строк 729-730. Следите за движением рук.
>
> ts->addedPackages -- это некоторая структура данных, которая содержит
> ts->addedPackages.list -- указатель на массив, выделяемый в куче.
> Функция alAddPackage() добавляет новый элемент в этот массив и возвращает
> на него указатель. Соответственно (по правилам типизированной адресной
> арифметики) переменная alNum -- это будет индекс последнего добавленного
> элемента в массиве.
>
> Но! Когда массив становится слишком маленьким, функция alAddPackage()
> делает realloc этого массива (строка 237). Соотвественно, адрес массива
> ts->addedPackages.list может измениться.
>
> Теперь посмотрим на вычитание указателей в строках 729-730. Левый
> операнд вычитания может изменить ts->addedPackages.list, а правым
> операндом является сам ts->addedPackages.list. Получается, что этот
> код зависит от порядка вычисления операндов -- а именно, может
> использоваться либо старое значение ts->addedPackages.list, либо
> уже новое значение.
>
> Воопрос соответствено насколько легален этот код, и вообще любая
> нетривиальная информация на эту тему.
ISO/IEC 9899:TC2
6.5 Expressions
3 The grouping of operators and operands is indicated by the syntax.
Except as specified
later (for the function-call (), &&, ||, ?:, and comma operators), the
order of evaluation
of subexpressions and the order in which side effects take place are
both unspecified.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 5:02 ` Kirill A. Shutemov
@ 2009-10-01 5:09 ` Kirill A. Shutemov
0 siblings, 0 replies; 13+ messages in thread
From: Kirill A. Shutemov @ 2009-10-01 5:09 UTC (permalink / raw)
To: ALT Linux Team development discussions
2009/10/1 Kirill A. Shutemov <kirill@shutemov.name>:
> 2009/10/1 Alexey Tourbin <at@altlinux.ru>:
>> У нас в rpm есть такой код.
>>
>> lib/depends.h:
>> 108 typedef /*@abstract@*/ struct availableList_s {
>> 109 /*@owned@*/ /*@null@*/ struct availablePackage * list; /*!< Set of packages. */
>> 110 struct availableIndex index; /*!< Set of available items. */
>> 111 int delta; /*!< Delta for pkg list reallocation. */
>> 112 int size; /*!< No. of pkgs in list. */
>> 113 int alloced; /*!< No. of pkgs allocated for list. */
>> 114 int numDirs; /*!< No. of directories. */
>> 115 /*@owned@*/ /*@null@*/ dirInfo dirs; /*!< Set of directories. */
>> 116 } * availableList;
>> ...
>>
>> lib/depends.c:
>> 213 static /*@exposed@*/ struct availablePackage *
>> 214 alAddPackage(availableList al,
>> 215 Header h, /*@null@*/ /*@dependent@*/ const void * key,
>> 216 /*@null@*/ FD_t fd, /*@null@*/ rpmRelocation * relocs)
>> 217 /*@modifies al, h @*/
>> 218 {
>> 219 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
>> 220 HFD_t hfd = headerFreeData;
>> 221 rpmTagType dnt, bnt;
>> 222 struct availablePackage * p;
>> 223 rpmRelocation * r;
>> 224 int i;
>> 225 int_32 * dirIndexes;
>> 226 const char ** dirNames;
>> 227 int numDirs, dirNum;
>> 228 int * dirMapping;
>> 229 struct dirInfo_s dirNeedle;
>> 230 dirInfo dirMatch;
>> 231 int first, last, fileNum;
>> 232 int origNumDirs;
>> 233 int pkgNum;
>> 234
>> 235 if (al->size == al->alloced) {
>> 236 al->alloced += al->delta;
>> 237 al->list = xrealloc(al->list, sizeof(*al->list) * al->alloced);
>> 238 }
>> ...
>> 703 int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
>> 704 const void * key, int upgrade, rpmRelocation * relocs)
>> 705 {
>> 706 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
>> 707 HFD_t hfd = headerFreeData;
>> 708 rpmTagType ont, ovt;
>> 709 /* this is an install followed by uninstalls */
>> 710 const char * name;
>> 711 int count;
>> 712 const char ** obsoletes;
>> 713 int alNum;
>> 714
>> 715 /*
>> 716 * FIXME: handling upgrades like this is *almost* okay. It doesn't
>> 717 * check to make sure we're upgrading to a newer version, and it
>> 718 * makes it difficult to generate a return code based on the number of
>> 719 * packages which failed.
>> 720 */
>> 721 if (ts->orderCount == ts->orderAlloced) {
>> 722 ts->orderAlloced += ts->delta;
>> 723 ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
>> 724 }
>> 725 ts->order[ts->orderCount].type = TR_ADDED;
>> 726 if (ts->addedPackages.list == NULL)
>> 727 return 0;
>> 728
>> 729 alNum = alAddPackage(&ts->addedPackages, h, key, fd, relocs) -
>> 730 ts->addedPackages.list;
>> 731 ts->order[ts->orderCount++].u.addedIndex = alNum;
>> ...
>>
>> Вопрос касается строк 729-730. Следите за движением рук.
>>
>> ts->addedPackages -- это некоторая структура данных, которая содержит
>> ts->addedPackages.list -- указатель на массив, выделяемый в куче.
>> Функция alAddPackage() добавляет новый элемент в этот массив и возвращает
>> на него указатель. Соответственно (по правилам типизированной адресной
>> арифметики) переменная alNum -- это будет индекс последнего добавленного
>> элемента в массиве.
>>
>> Но! Когда массив становится слишком маленьким, функция alAddPackage()
>> делает realloc этого массива (строка 237). Соотвественно, адрес массива
>> ts->addedPackages.list может измениться.
>>
>> Теперь посмотрим на вычитание указателей в строках 729-730. Левый
>> операнд вычитания может изменить ts->addedPackages.list, а правым
>> операндом является сам ts->addedPackages.list. Получается, что этот
>> код зависит от порядка вычисления операндов -- а именно, может
>> использоваться либо старое значение ts->addedPackages.list, либо
>> уже новое значение.
>>
>> Воопрос соответствено насколько легален этот код, и вообще любая
>> нетривиальная информация на эту тему.
>
> ISO/IEC 9899:TC2
>
> 6.5 Expressions
>
> 3 The grouping of operators and operands is indicated by the syntax.
> Except as specified
> later (for the function-call (), &&, ||, ?:, and comma operators), the
> order of evaluation
> of subexpressions and the order in which side effects take place are
> both unspecified.
>
6.5.2.2 Function calls
12 EXAMPLE In the function call
(*pf[f1()]) (f2(), f3() + f4())
the functions f1, f2, f3, and f4 may be called in any order. All side
effects have to be completed before
the function pointed to by pf[f1()] is called
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 1:24 [devel] вопрос по языку Си - порядок вычисления операндов Alexey Tourbin
2009-10-01 5:00 ` Damir Shayhutdinov
2009-10-01 5:02 ` Kirill A. Shutemov
@ 2009-10-01 8:31 ` Kharitonov A. Dmitry
2009-10-01 8:36 ` Kharitonov A. Dmitry
` (2 more replies)
2 siblings, 3 replies; 13+ messages in thread
From: Kharitonov A. Dmitry @ 2009-10-01 8:31 UTC (permalink / raw)
To: ALT Linux Team development discussions
Alexey Tourbin wrote:
> У нас в rpm есть такой код.
>
> lib/depends.h:
> 108 typedef /*@abstract@*/ struct availableList_s {
> 109 /*@owned@*/ /*@null@*/ struct availablePackage * list; /*!< Set of packages. */
> 110 struct availableIndex index; /*!< Set of available items. */
> 111 int delta; /*!< Delta for pkg list reallocation. */
> 112 int size; /*!< No. of pkgs in list. */
> 113 int alloced; /*!< No. of pkgs allocated for list. */
> 114 int numDirs; /*!< No. of directories. */
> 115 /*@owned@*/ /*@null@*/ dirInfo dirs; /*!< Set of directories. */
> 116 } * availableList;
> ...
>
> lib/depends.c:
> 213 static /*@exposed@*/ struct availablePackage *
> 214 alAddPackage(availableList al,
> 215 Header h, /*@null@*/ /*@dependent@*/ const void * key,
> 216 /*@null@*/ FD_t fd, /*@null@*/ rpmRelocation * relocs)
> 217 /*@modifies al, h @*/
> 218 {
> 219 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
> 220 HFD_t hfd = headerFreeData;
> 221 rpmTagType dnt, bnt;
> 222 struct availablePackage * p;
> 223 rpmRelocation * r;
> 224 int i;
> 225 int_32 * dirIndexes;
> 226 const char ** dirNames;
> 227 int numDirs, dirNum;
> 228 int * dirMapping;
> 229 struct dirInfo_s dirNeedle;
> 230 dirInfo dirMatch;
> 231 int first, last, fileNum;
> 232 int origNumDirs;
> 233 int pkgNum;
> 234
> 235 if (al->size == al->alloced) {
> 236 al->alloced += al->delta;
> 237 al->list = xrealloc(al->list, sizeof(*al->list) * al->alloced);
> 238 }
> ...
> 703 int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
> 704 const void * key, int upgrade, rpmRelocation * relocs)
> 705 {
> 706 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
> 707 HFD_t hfd = headerFreeData;
> 708 rpmTagType ont, ovt;
> 709 /* this is an install followed by uninstalls */
> 710 const char * name;
> 711 int count;
> 712 const char ** obsoletes;
> 713 int alNum;
> 714
> 715 /*
> 716 * FIXME: handling upgrades like this is *almost* okay. It doesn't
> 717 * check to make sure we're upgrading to a newer version, and it
> 718 * makes it difficult to generate a return code based on the number of
> 719 * packages which failed.
> 720 */
> 721 if (ts->orderCount == ts->orderAlloced) {
> 722 ts->orderAlloced += ts->delta;
> 723 ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
> 724 }
> 725 ts->order[ts->orderCount].type = TR_ADDED;
> 726 if (ts->addedPackages.list == NULL)
> 727 return 0;
> 728
> 729 alNum = alAddPackage(&ts->addedPackages, h, key, fd, relocs) -
> 730 ts->addedPackages.list;
> 731 ts->order[ts->orderCount++].u.addedIndex = alNum;
> ...
>
> Вопрос касается строк 729-730. Следите за движением рук.
>
> ts->addedPackages -- это некоторая структура данных, которая содержит
> ts->addedPackages.list -- указатель на массив, выделяемый в куче.
> Функция alAddPackage() добавляет новый элемент в этот массив и возвращает
> на него указатель. Соответственно (по правилам типизированной адресной
> арифметики) переменная alNum -- это будет индекс последнего добавленного
> элемента в массиве.
>
> Но! Когда массив становится слишком маленьким, функция alAddPackage()
> делает realloc этого массива (строка 237). Соотвественно, адрес массива
> ts->addedPackages.list может измениться.
>
> Теперь посмотрим на вычитание указателей в строках 729-730. Левый
> операнд вычитания может изменить ts->addedPackages.list, а правым
> операндом является сам ts->addedPackages.list. Получается, что этот
> код зависит от порядка вычисления операндов -- а именно, может
> использоваться либо старое значение ts->addedPackages.list, либо
> уже новое значение.
>
> Воопрос соответствено насколько легален этот код, и вообще любая
> нетривиальная информация на эту тему.
>
Неоднократно натыкался на такое:
исходное выражение а+b+c
менялся порядок вычисления случайным образом
то так
а+(b+c)
то так
(а+b)+c
то так
(с+b)+a
естественно получалась случайно работающая программа. Багу ловил 3 месяца.
Во всех руководствах написано, что расстановка скобок принудительно
должна обеспечивать порядок вычислений, но я опять таки натыкался на
отступления и от этого. Разбивание выражения с применением промежуточной
переменной однозначно определяло порядок, именно тот, который мне нужен.
Промежуточная переменная в конечном коде в результате оптимизации исчезала.
Так же трудно уловимый баг связан с подстановкой в аргументы функции
скрытых временных особенно, если эти аргументы помеченны модификатором
const.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 8:31 ` Kharitonov A. Dmitry
@ 2009-10-01 8:36 ` Kharitonov A. Dmitry
2009-10-01 9:16 ` Kirill A. Shutemov
2009-10-01 9:30 ` Led
2 siblings, 0 replies; 13+ messages in thread
From: Kharitonov A. Dmitry @ 2009-10-01 8:36 UTC (permalink / raw)
To: ALT Linux Team development discussions
>> Воопрос соответствено насколько легален этот код, и вообще любая
>> нетривиальная информация на эту тему.
Я считаю, что этот код не рабочий и передаю вам своё искреннее уважение,
за обнаружение этой ошибки.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 8:31 ` Kharitonov A. Dmitry
2009-10-01 8:36 ` Kharitonov A. Dmitry
@ 2009-10-01 9:16 ` Kirill A. Shutemov
2009-10-01 9:47 ` Kharitonov A. Dmitry
2009-10-01 9:30 ` Led
2 siblings, 1 reply; 13+ messages in thread
From: Kirill A. Shutemov @ 2009-10-01 9:16 UTC (permalink / raw)
To: ALT Linux Team development discussions
2009/10/1 Kharitonov A. Dmitry <kharpost@rambler.ru>:
> Неоднократно натыкался на такое:
> исходное выражение а+b+c
> менялся порядок вычисления случайным образом
> то так
> а+(b+c)
> то так
> (а+b)+c
> то так
> (с+b)+a
> естественно получалась случайно работающая программа. Багу ловил 3 месяца.
Link?
> Во всех руководствах написано, что расстановка скобок принудительно должна
> обеспечивать порядок вычислений, но я опять таки натыкался на отступления и
> от этого. Разбивание выражения с применением промежуточной переменной
> однозначно определяло порядок, именно тот, который мне нужен. Промежуточная
> переменная в конечном коде в результате оптимизации исчезала.
> Так же трудно уловимый баг связан с подстановкой в аргументы функции скрытых
> временных особенно, если эти аргументы помеченны модификатором const.
>
> _______________________________________________
> Devel mailing list
> Devel@lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 8:31 ` Kharitonov A. Dmitry
2009-10-01 8:36 ` Kharitonov A. Dmitry
2009-10-01 9:16 ` Kirill A. Shutemov
@ 2009-10-01 9:30 ` Led
2 siblings, 0 replies; 13+ messages in thread
From: Led @ 2009-10-01 9:30 UTC (permalink / raw)
To: ALT Linux Team development discussions
On Thursday, 01 October 2009 11:31:39 Kharitonov A. Dmitry wrote:
> Неоднократно натыкался на такое:
> исходное выражение а+b+c
> менялся порядок вычисления случайным образом
> то так
> а+(b+c)
> то так
> (а+b)+c
> то так
> (с+b)+a
> естественно получалась случайно работающая программа. Багу ловил 3 месяца.
> Во всех руководствах написано, что расстановка скобок принудительно
> должна обеспечивать порядок вычислений,
Это ещё нужно постараться, чтобы найти такое рукоблу^H^H^Hводство. Ни в одном
стандарте этого нет.
> но я опять таки натыкался на
> отступления и от этого. Разбивание выражения с применением промежуточной
> переменной однозначно определяло порядок, именно тот, который мне нужен.
> Промежуточная переменная в конечном коде в результате оптимизации исчезала.
> Так же трудно уловимый баг связан с подстановкой в аргументы функции
> скрытых временных особенно, если эти аргументы помеченны модификатором
> const.
--
Led
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 9:16 ` Kirill A. Shutemov
@ 2009-10-01 9:47 ` Kharitonov A. Dmitry
2009-10-01 9:51 ` Kirill A. Shutemov
0 siblings, 1 reply; 13+ messages in thread
From: Kharitonov A. Dmitry @ 2009-10-01 9:47 UTC (permalink / raw)
To: ALT Linux Team development discussions
> Link?
>
>
К сожалению не дам. Не помню в каких программах это было и тем более в
каком месте.
Собственно я такие баги стал замечать после прочтения книжки что-то там
скользкие места с++ (я такую подлость просто не ожидал от компилятора).
Книжка в pdf где-то лежит, могу переслать в личку.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 9:47 ` Kharitonov A. Dmitry
@ 2009-10-01 9:51 ` Kirill A. Shutemov
2009-10-01 10:10 ` Kharitonov A. Dmitry
0 siblings, 1 reply; 13+ messages in thread
From: Kirill A. Shutemov @ 2009-10-01 9:51 UTC (permalink / raw)
To: ALT Linux Team development discussions
2009/10/1 Kharitonov A. Dmitry <kharpost@rambler.ru>:
>
>> Link?
>>
>>
>
> К сожалению не дам. Не помню в каких программах это было и тем более в каком
> месте.
> Собственно я такие баги стал замечать после прочтения книжки что-то там
> скользкие места с++ (я такую подлость просто не ожидал от компилятора).
> Книжка в pdf где-то лежит, могу переслать в личку.
Я думаю, что это не баг, а незнание инструмента. Порядок вычисления операндов
по стандарту никто не гарантирует. Было бы интересно посмотреть на конкретный
пример где есть "баг".
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 9:51 ` Kirill A. Shutemov
@ 2009-10-01 10:10 ` Kharitonov A. Dmitry
2009-10-01 10:14 ` Damir Shayhutdinov
0 siblings, 1 reply; 13+ messages in thread
From: Kharitonov A. Dmitry @ 2009-10-01 10:10 UTC (permalink / raw)
To: ALT Linux Team development discussions
Kirill A. Shutemov wrote:
> 2009/10/1 Kharitonov A. Dmitry <kharpost@rambler.ru>:
>
>>> Link?
>>>
>>>
>>>
>> К сожалению не дам. Не помню в каких программах это было и тем более в каком
>> месте.
>> Собственно я такие баги стал замечать после прочтения книжки что-то там
>> скользкие места с++ (я такую подлость просто не ожидал от компилятора).
>> Книжка в pdf где-то лежит, могу переслать в личку.
>>
>
> Я думаю, что это не баг, а незнание инструмента. Порядок вычисления операндов
> по стандарту никто не гарантирует. Было бы интересно посмотреть на конкретный
> пример где есть "баг".
>
С позиции программиста это возможно это не баг. А вот с позиции
пользователя -- это очевидный баг -- программа-то "глючит". Я в таких
ситуациях принимаю позицию пользователя. Ну у меня вместо abc были
вызовы функций, инкремент и пр.
Портя разночтение: какой баг вы имеете в виду баг приложения или баг
компилятора? gcc в таких местах выдаёт предупреждения, правда не всегда,
в одном месте, где я 3 месяца искал ошибку в "правильно" написанной
программе предупреждений не было.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 10:10 ` Kharitonov A. Dmitry
@ 2009-10-01 10:14 ` Damir Shayhutdinov
2009-10-01 10:32 ` Kharitonov A. Dmitry
0 siblings, 1 reply; 13+ messages in thread
From: Damir Shayhutdinov @ 2009-10-01 10:14 UTC (permalink / raw)
To: ALT Linux Team development discussions
> С позиции программиста это возможно это не баг. А вот с позиции пользователя
> -- это очевидный баг -- программа-то "глючит". Я в таких ситуациях принимаю
> позицию пользователя. Ну у меня вместо abc были вызовы функций, инкремент и
> пр.
Есть простой совет - не злоупотреблять функциями с побочными
эффектами. Один побочный эффект на выражение - достаточно.
Так и карма будет лучше, и волосы будут мягкими и шелковистыми.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [devel] вопрос по языку Си - порядок вычисления операндов
2009-10-01 10:14 ` Damir Shayhutdinov
@ 2009-10-01 10:32 ` Kharitonov A. Dmitry
0 siblings, 0 replies; 13+ messages in thread
From: Kharitonov A. Dmitry @ 2009-10-01 10:32 UTC (permalink / raw)
To: ALT Linux Team development discussions
Damir Shayhutdinov wrote:
>> С позиции программиста это возможно это не баг. А вот с позиции пользователя
>> -- это очевидный баг -- программа-то "глючит". Я в таких ситуациях принимаю
>> позицию пользователя. Ну у меня вместо abc были вызовы функций, инкремент и
>> пр.
>>
>
> Есть простой совет - не злоупотреблять функциями с побочными
> эффектами. Один побочный эффект на выражение - достаточно.
>
> Так и карма будет лучше, и волосы будут мягкими и шелковистыми.
>
все бы так думали.... Только всё чаще попадаются чужие программы, у
авторов которых толи что-то с руками, толи у меня что-то не в порядке,
приходится часто код переписывать -- когда чужая программа выходит из
под меня -- ответственность уже несу я, а не дядя вася, который по этой
программе уже отчитался, получил деньги и претензий не принимает, в
акте-то написано, что претензий нет.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-10-01 10:32 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-01 1:24 [devel] вопрос по языку Си - порядок вычисления операндов Alexey Tourbin
2009-10-01 5:00 ` Damir Shayhutdinov
2009-10-01 5:02 ` Kirill A. Shutemov
2009-10-01 5:09 ` Kirill A. Shutemov
2009-10-01 8:31 ` Kharitonov A. Dmitry
2009-10-01 8:36 ` Kharitonov A. Dmitry
2009-10-01 9:16 ` Kirill A. Shutemov
2009-10-01 9:47 ` Kharitonov A. Dmitry
2009-10-01 9:51 ` Kirill A. Shutemov
2009-10-01 10:10 ` Kharitonov A. Dmitry
2009-10-01 10:14 ` Damir Shayhutdinov
2009-10-01 10:32 ` Kharitonov A. Dmitry
2009-10-01 9:30 ` Led
ALT Linux Team development discussions
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
public-inbox-index devel
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.devel
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git