LINUX.ORG.RU

неявное преобразование типов в с++


0

2

пишется программка на с++, в ней подключаются системные заголовочные файлы. в одном из этих файлов есть примерно такой кусок кода:
static __inline __ int* foo()
{
int *asd;
....
return (void*)asd + 10;
}
компилятор с++ тут-же вскидывается на неявное преобразование. если писать на с, а не на с++ все нормально. как-нибудь можно компилятору сказать, чтобы он на это внимание не обращал?

★★

Чо?

(void*)asd + 10;

Да ты гонишь. Это бессмысленно без типа указателя, т. е. с void*.

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

ну вот помнил же что такое такое ))) спасибо. заработало

Vinill ★★
() автор топика

В данной ситуации сдвиг на 10 байт - это какая-то очень тёмная магия. Даже интересно, зачем это нужно.

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

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

Вместо этого ты предлагаешь позволить это раковой опухоли расти.

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

Давай ссылку на исходник, а не жужжи.

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

Судя по всему, у этого говнокода есть исходник.

«в ней подключаются системные заголовочные файлы. в одном из этих файлов»

wota ★★
()

компилятор с++ тут-же вскидывается на неявное преобразование

Ну так да: в последней строчке есть неявное преобразование void* -> int*. Стрелять в ногу правильно нужно как-то так: return (int*)((void*)asd+10);

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

тогда (char*), ибо для арифметики с указателями нужно знать размер данных "(char*)p + 1" сдвинет на 1 байт, а "(uint32_t*)p + 1" - на 4.

Я не уверен, что ТС говорит правду про «системные» заголовочные файлы.

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

это не безсмысленно а просто не переносимо

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

Давай ссылку на исходник, а не жужжи.
anonymous (05.02.2013 14:40:35)
/usr/include/linux тебе в дорогу. чисти эту опухоль )))))

Может они хотят побайтово с числами работать, эти юные взрывотехники.
dmfd (05.02.2013 14:40:36)
это просто как показательный пример. или ты думал, что в ядре тоже функции foo попадаются? ))

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

Арифметика для void* вроде так же, как и для char* работает. Точно не знаю, поскольку таким добром не обмазываюсь.

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

Арифметика для void* вроде так же, как и для char* работает

только в C. в C++ она запрещена, т.к. void - неполный тип

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

А с -fpermissive он и своём коде говна не заметит.

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

Да дело даже не в том, запрещена или разрешена (говорят, это вообще фича gcc), а в том, что гладя на этот код х. поймёшь, что он сделает. Это как ++i+++i.

anonymous
()

return (void*)asd + 10;

Так разве вообще можно?

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

Ну вот. ТС не стоит использовать этот файл [1], а стоит заиметь собственную функцию.

[1] http://osdir.com/ml/security.firewalls.netfilter.devel/2002-09/msg00083.html

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

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

*facepalm*

Думай уже своей башкой.

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

Да ты гонишь. Это бессмысленно без типа указателя, т. е. с void*.

В GCC с включенными расширениями sizeof(void*) == sizeof(char*).

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

Стрелять в ногу правильно нужно как-то так: return (int*)((void*)asd+10);

Ъ-С++ way:

return reinterpret_cast<int*>(static_cast<void*>(asd) + 10);

Места выстрелов потом легко грепаются.

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

Так, конечно, правильнее, но такой код обратно в ядро линукса не засунешь.

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

В GCC с включенными расширениями sizeof(void*) == sizeof(char*).

lol.

sizeof(WTF*) всегда равен размеру указателя (извини за тавтологию, но ты первый начал)

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

Да ёшкин код, вы вообще проблему не понимаете?

static_cast<void*>(asd) + 10 - в принципе воняет, не важно как вы кастуете к void*.

Кастовать надо к char*.

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

Да, арифметика указателей для void* по идее смысла не имеет, но компилятор и не такое пережёвывал.

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

Если компилятор у тебя даже на main() не ругнулся, то у меня плохие новости для тебя.

# LANG=C g++ test.cpp -Wall
test.cpp:1:7: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
test.cpp: In function 'int main()':
test.cpp:4:65: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
test.cpp:4:10: warning: unused variable 'foo' [-Wunused-variable]
test.cpp:4:67: warning: 'asd' is used uninitialized in this function [-Wuninitialized]
[/code[
anonymous
()
Ответ на: комментарий от anonymous

Если компилятор у тебя даже на main()

Охщи, я не нарочно.

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

Вы слишком хорошо думаете о языке C++: http://ideone.com/BvbWoe

просто надо пользоваться компиляторами C++, а не gcc:

1.cpp:1:1: error: C++ requires a type specifier for all declarations
main ()
^~~~
1.cpp:4:63: error: arithmetic on a pointer to void
    int* foo = reinterpret_cast<int*>(static_cast<void*>(asd) + 10);
                                      ~~~~~~~~~~~~~~~~~~~~~~~ ^
2 errors generated.
wota ★★
()
Последнее исправление: wota (всего исправлений: 2)
Ответ на: комментарий от Reset

Опечатался конечно: в GNU C sizeof(void) == sizeof(char) == 1:

> cat foo.c
#include <stdio.h>
int main()
{
  printf("%lu\n", sizeof(void));
}
> gcc -o foo foo.c
> ./foo
1
Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Прекратите писать для компилятора. Пишите для людей.

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