|
Компилятор Gcc или так и должнобыть?, Почему то отказывается выполнять инструкциии |
|
|
|
May 2 2008, 04:17
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 29-12-04
Пользователь №: 1 738

|
Столкнулся с тем что GCC упорно не хочет выполнять следующее, вроде с синтаксисом нет никакого криминала комерческие компиляторы отрабатывают без проблем (Borlad c++ и пр.) не выдавая никаких ошибок и предупреждений
unsigned long int a[] = {1, 2, 3, 4, 5}; unsigned long int b[5];
void* ptr = a;
b[0] = *((unsigned long int*)ptr)++; b[1] = *((unsigned long long int*)ptr)++;
В обоих случаях отказывается делать инкремент указателя выдавая ошибку хотя здесь явно указатель приводится к указателю на заданный тип, пробовал указатель описать как указатель на тип char или int ситуация не меняется. С точки зрения синтаксиса вроде всё правильно .. пытался искать в стандарте Ansi C но нашел ничего .. Мож у кого есть какие мысли .. не исключаю что может и я что то делаю не коррекктно.. Конечно эту ситуацию можно обойти... Спасибо.
|
|
|
|
|
 |
Ответов
|
May 2 2008, 08:23
|

Местный
  
Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720

|
Цитата А вот этого не надо, если в оригинальном варианте некоторые компиляторы формально что-могут сделать и оттделаться Warnigs, то тут уже явная ошибка. какая ? компилируется нормально, без предупреждений. то есть если нужно инкрементировать указатель, приведенный к другому типу : Код b[0] = *((unsigned long int *)ptr++); а если содержимое этого указателя, то нужно добавить внешние скобки : Код b[0] = (*((unsigned long int *)ptr))++; в обоих случаях нет никаких предупреждений.
|
|
|
|
|
May 2 2008, 08:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(umup @ May 2 2008, 10:23)  какая ? Что-то типа, что c операциями с указателеми на void придется обломиться. Цитата компилируется нормально, без предупреждений. Имя компилятора в студию  Цитата(ReAl @ May 2 2008, 10:33)  А вот инкремент указателя на void - это, кажется, "неопределённое поведение". Без "кажется" - компилятор который молча инкрементирует указатель на неизвестный объект не может быть признан компилятором
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 2 2008, 09:02
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(zltigo @ May 2 2008, 11:38)  Имя компилятора в студию  ... Без "кажется" - компилятор который молча инкрементирует указатель на неизвестный объект не может быть признан компилятором  Ну, несколько я понимаю, "неопределённое поведение" означает, что компилятор может (имеет право) что-то сделать так или сяк, а молча ли он это сделает - зависит от включенного уровня предупреждений. Учитывая Сейчас проверил Код i = *((int*)ptr++); gcc в данном месте независимо от размера объекта, к указателю на который делается приведение, увеличивает ptr на 1 (его право в случае UB), если есть ключ --pedantic, то выдаёт Цитата warning: wrong type argument to increment Просто -Wall -Wextra для этого мало (для предупреждения на i = i++ их достаточно). Цитата(aesok @ May 2 2008, 11:44)  А если не молча, если про это в документации написано... ... Цитата The option `-Wpointer-arith' requests a warning if these extensions are used. Хм, я был уверен, что -Wall -Wextra включают все предпреждения... Надо ещё раз перед сном перечитать документацию :-)
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 2 2008, 09:36
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 29-12-04
Пользователь №: 1 738

|
Я пробовал в Borland C++ Builder6, там всё проходит.. Конечно эту ситуацию можно обойти очень легко.. .Просто я вроде явно привожу указатель ок определённому типу информирую компилятор о том на объект какого типа он ссылается причём приведение типа срабатывает а вот инкремент нет.. причем дело тут не в void* можно указатель описать и как char* результат будет тот же. Не исключаю что косяк в моей голове.. Просто иногда очень удобено описать указатель на массив как void* и по ходу дела приводить и его к разным типам разыменовывая содержимое буферного массива чтобы не создавать кучу разных указателей на разные типы данных.. Опять же не утверждаю и не настаиваю что я прав я вполне могу ошибаться.  . Спасибо.
|
|
|
|
|
May 2 2008, 14:58
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Олег. @ May 2 2008, 13:36)  Не исключаю что косяк в моей голове.. А почему бы не сделать сразу этот указатель на unsigned long - и не придется ничего преобразовывать? Цитата(Олег. @ May 2 2008, 13:36)  Просто иногда очень удобено описать указатель на массив как void* и по ходу дела приводить и его к разным типам разыменовывая содержимое буферного массива чтобы не создавать кучу разных указателей на разные типы данных.. Ты пишешь на Си, а думаешь на ассемблере, и пытаешься помочь компилятору. Сделай над собой усилие и забудь об ассемблере - напиши программу, думая только об алгоритме. С твоей стороны помощь компилятору может заключаться в том, чтобы локализовать использование каждой переменной - объявлять ее только в той области видимости, где она используется, и минимизировать количество глобальных переменных.
|
|
|
|
|
May 2 2008, 15:55
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 29-12-04
Пользователь №: 1 738

|
Да Вы в общем то правы. Да я пишу на С но всегда копаюсь в скомпилированом коде ассемблера. Как ни крути ну сильна привычка и любовь к железу.. пока не могу оторваться ибо до этого много работал на ассемблере. С приобретением опыта программирования на С думаю это пройдет но пока стараюсь и учусь. Спасибо.
|
|
|
|
Сообщений в этой теме
Олег. Компилятор Gcc или так и должнобыть? May 2 2008, 04:17 forever failure Видимо имеется ввиду это:
warning: use of cast exp... May 2 2008, 04:43 777777 Цитата(Олег. @ May 2 2008, 08:17) Столкну... May 2 2008, 05:46 zltigo Цитата(777777 @ May 2 2008, 07:46) Борлан... May 2 2008, 07:13 umup попробуйте так :
Код b[0] = *((u... May 2 2008, 06:48 ReAl Цитата(umup @ May 2 2008, 09:48) попробуй... May 2 2008, 08:33 ReAl Цитата(Олег. @ May 2 2008, 07:17) вроде с... May 2 2008, 08:08  aesok Цитата(zltigo @ May 2 2008, 12:38) Без ... May 2 2008, 08:44   zltigo Цитата(aesok @ May 2 2008, 10:44) А если ... May 2 2008, 08:48      777777 Цитата(Олег. @ May 2 2008, 19:55) Да Вы в... May 2 2008, 16:09   zltigo Цитата(ReAl @ May 2 2008, 11:02) gcc в да... May 2 2008, 09:41 umup можно так :
Код b[0] = *(unsigned long... May 2 2008, 10:30 Олег. Да конечно так можно.. Я понимаю.. До меня дошло ч... May 2 2008, 11:52 Andreas1 поскольку только осваиваюсь в сях, а ситуация инте... May 2 2008, 17:12 AHTOXA Цитата(Andreas1 @ May 2 2008, 23:12) И де... May 2 2008, 17:35 ReAl Цитата(Andreas1 @ May 2 2008, 20:12) поск... May 2 2008, 19:15 Alex03 А если так:
Кодunuon
{
char *pc;
int *pi;
long... May 5 2008, 12:01 777777 Цитата(Alex03 @ May 5 2008, 16:01) А если... May 6 2008, 16:53  AHTOXA Цитата(777777 @ May 6 2008, 22:53) Так мо... May 6 2008, 18:45   777777 Цитата(AHTOXA @ May 6 2008, 22:45) А нель... May 7 2008, 04:18    AHTOXA Цитата(777777 @ May 7 2008, 10:18) Очень ... May 7 2008, 04:54     777777 Цитата(AHTOXA @ May 7 2008, 08:54) Собств... May 7 2008, 05:00      AHTOXA Цитата(777777 @ May 7 2008, 11:00) Вы тож... May 7 2008, 05:03       Сергей Борщ Цитата(AHTOXA @ May 7 2008, 08:03) Спасиб... May 7 2008, 06:48        777777 Цитата(Сергей Борщ @ May 7 2008, 10:48) М... May 7 2008, 07:38         ReAl Цитата(777777 @ May 7 2008, 10:38) Если у... May 7 2008, 09:30          777777 Цитата(ReAl @ May 7 2008, 13:30) Никто ни... May 7 2008, 11:46           ReAl Цитата(777777 @ May 7 2008, 14:46) Все эт... May 7 2008, 12:59         Сергей Борщ Цитата(777777 @ May 7 2008, 10:38) А вот ... May 7 2008, 09:51        AHTOXA Цитата(Сергей Борщ @ May 7 2008, 12:48) М... May 7 2008, 07:56 alexander55 Цитата(Олег. @ May 2 2008, 08:17) unsigne... May 7 2008, 10:02
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|