Сейчас на форуме: zombi-vadim, zds (+4 невидимых)

 eXeL@B —› Программирование —› GCC и include
<< . 1 . 2 . 3 . >>
Посл.ответ Сообщение


Ранг: 105.6 (ветеран), 36thx
Активность: 0.10
Статус: Участник

Создано: 21 октября 2013 17:57 · Поправил: Dart Sergius
· Личное сообщение · #1

С радости что вышел gcc 4.8.1, я сдуру ума взял себе его и поставил.
И так как я пишу используя Qt - то естественно захотелось перекомпилить(ну и нужда то что с новым gcc собирается и падает все).
Все впринципе проходило хорошо, сконфигурировал , поставил компилить, и тут посыпались веселые приколюхи.
Одним словом, make работающий в 2 потока вывалил мне около 8000 строк ошибок. Все село к 1-му файлу:
wtypes.h(использовался для ole.h,ole2.h, oleauto.h ...). Там обхявлялись структуры, которые потом использовались. Как бы include был сделан верно везде(местами ничего не перепутано и прочее). Но все равно сыпались ошибки.
Добавил флаг -E и увидел всю причину.
Этот файл добавлялся препроцессором в самом конце, уже после того как описывались файлы, в которых они использовались.
Практически перед "нашим кодом". Ну и естественно, находя вначале тип данных, описаный позже - он возмущался.
Неужели все сломали?

ах да, система у меня win xp, mingw

| Сообщение посчитали полезным: Abraham


Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 09 декабря 2013 02:20
· Личное сообщение · #2

вопросы к тем кто его собирал (компиль)
по умолчанию там отладочная инфа скомпилилась, а она по умолчанию не компилится нужно -g указывать
так же там за каким то Х включены вообще не нужные либы libgcc
которые тоже по умолчанию не линкуются вообщето



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 09 декабря 2013 02:39
· Личное сообщение · #3

reversecode пишет: вопросы к тем кто его собирал (компиль)
Еще такое дело, он собирал в 4.8+, а так есть такая шляпа, как быстрая сборка, никакой оптимизации, собирается абы запустилось, но быстрооо.
Еще там за каким то иксом инфа о фреймах, сапшены.. код унылый, но безопасный, аж жуть берет и это на одну строчку кода.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 09 декабря 2013 02:40 · Поправил: dosprog
· Личное сообщение · #4

Dr0p,
да нормально всё с Си.
Только вот с примером брейка неясно :

char BreakPoint[]={ /* массив байтов в сегменте данных. Лежит <int 3>, должно ещё лежать <retn> */
0xCC /* тут ещё ",0xC3" , если это будет WIN32-PE */ };

Вот для такого-то и лучше применять inline assembler. Хотя в примере - переносимый код для любого компилятора. Красиво.
А вообще, во многих реализациях есть директива типа __emit__(0xCC), для вставки байтов прямо в код. Удобно, но некрасиво и непереносимо.




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 03:06
· Личное сообщение · #5

dosprog

> __emit__(0xCC)

Не поддерживается походу.

Можите обьяснить почему эта конструкция:

void (__stdcall *BreakPoint)();

компилится в пустое место(никаких фейлов, компиль просто её игнорит)




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 09 декабря 2013 03:07 · Поправил: reversecode
· Личное сообщение · #6

а во что должна компилится пустая декларация?
точнее даже - обьявление типа




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 03:10
· Личное сообщение · #7

reversecode

На мой взгляд это был бы дефейн, если бы небыло в конце ().



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 09 декабря 2013 03:50 · Поправил: dosprog
· Личное сообщение · #8

Dr0p,
reversecode прав.

typedef void (__stdcall *BreakRef)(); /*Это объявление типа указателя на функцию, вызываемую по stdcall и не возвращающую никакого значения. Никакого кода/данных не генерируется. */
BreakRef BreakCall = (BreakRef)&BreakPoint[0]; /* Генерируется DWORD <BreakCall dd ?>, туда пишется адрес массива - Объявляем функию этого типа (BreakRef) и присваиваем ей адрес того массива байтов, где лежит 0xCC */
BreakCall(); /* вызываем код, лежащий в виде массива байтов, где ещё 0xCC. Но там же должен быть и <retn>. Генерируется <call dword ptr BreakCall> */

-- ADD --
Поправил. Я взял код изначального примера.

P.S. Разбор выражения typedef идёт справа налево, например:
"()" - функция
"BreakRef" - именование типа
"*" - указатель на неё (на функцию)
"__stdcall" - модификатор типа вызова
"void" - возвращаемое той функцией значение

P.P.S
void (__stdcall *BreakRef)();
- видимо, компилятор воспринимает это как пред-декларацию функции без аргументов, возвращающей void* (EAX=указатель), и подробно она должна была быть описана далее.
Если бы дальше последовал вызов BreakRef(), вывалилось бы несколько ошибок компиляции.
Что тут ещё предположить...
За такие "штучки" людям и нравится язык Си.




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 04:13
· Личное сообщение · #9

dosprog

Вы видите выше typedef ?




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 06:24 · Поправил: Dr0p
· Личное сообщение · #10

dosprog

typedef void (__stdcall *BreakRef)(); это дефейн типа, прототипа ссылки на функцию, тип её, конвенция и аргументы.

BreakRef BreakCall = (BreakRef)&BreakPoint[0]; это аллокация переменной BreakCall с типом BreakRef и присвоение ей ссылки на массив:

mov [esp + N],offset BreakPoint

В конструкции выше (BreakRef) совсем не нужен, но без этого выводится варнинг, хотя и конпилится без изменений.

BreakCall();

mov eax, [esp + N]
call eax

Логично предположить что можно оптимизировать, удалив не нужную переменную и тип:

void (__stdcall *BreakPoint)(); содержит всю необходимую конпилю инфу - прототип, конвенцию и раскрытие ссылки, адрес которой непосредственно задан. Но синтаксис ущербный и совсем не логичный.

1. Дефейн типа, описывающего прототип.
2. Дефейн переменной с созданным типом.
3. Присвоение переменной значения адреса массива.
4. Разименование переменной.
5. Вызов вектора.

Очевидно что шаги 2, 3, 4 паразитные. Вот она гибкость

Если переменную сделать регистровой:

register BreakRef BreakCall...:

mov ebx,0x404000
call ebx

Использование переменной вообще теряет всякий смысл. Но компиль всё равно выделяет её в локалях. Я это вообще понять не могу.

За такие "штучки" людям и не нравится язык Си.




Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 09 декабря 2013 06:54
· Личное сообщение · #11

Veliant пишет:
На сколько знаю intel'овский компилятор в плане оптимизаций рулит


был замечен в опускании старых интеловских и всех амд-ешных камней.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 09 декабря 2013 07:50 · Поправил: dosprog
· Личное сообщение · #12

Dr0p,
захотели регистровую переменную - и получили

register BreakRef BreakCall...:
mov ebx,0x404000
call ebx

Зато теперь можно давать подряд сколько угодно:

call ebx
........
call ebx
........
call ebx
........

- оптимизация

Ну, а издержки-то будут по-любому. На асме можно сделать что угодно, но жизнь коротка...
Я стараюсь не применять такую оптимизацию (как это <call ebx>) , а на Си - почему бы и не загадать "register"?



Ранг: 44.8 (посетитель), 19thx
Активность: 0.040
Статус: Участник

Создано: 09 декабря 2013 10:00
· Личное сообщение · #13

бгг элита учит С



Ранг: 2.6 (гость), 4thx
Активность: 0=0
Статус: Участник

Создано: 09 декабря 2013 13:16
· Личное сообщение · #14

Dr0p пишет:
В конструкции выше (BreakRef) совсем не нужен, но без этого выводится варнинг, хотя и конпилится без изменений.

Можно и без доп. типа обойтись:

void (*BreakCall)() = (void (*)())&BreakPoint[0];




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 13:45 · Поправил: Dr0p
· Личное сообщение · #15

dosprog

> почему бы и не загадать "register"?

Потому что нужно гадать. Танцы с бубном. Во что оно скомпилится известно только тем двум барадатым дядькам.

AnTiDoD
Как по мне, так бессмысленное выражение. Функции нельзя присвоить значение.

SegFault

Что собстно смешного ?

У него множество диалектов, что один компиль съедает, другой выдаст фейл. Некоторые считают компиль чуть ли не святым граалем". Си это тупиковая ветвь в компиляции. Развилось оно в ооп костыли, это только усложнило коденг. Будущее за псевдокодом, это васико подобные языки. Они максимально краткие и близкие к псевдокоду.

Взять такую область, как метаморфизм. Никому на ум не придёт генерить сишный скрипт. Потому что он более громоздкий, чем конечный бинарнуй код.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 09 декабря 2013 13:49
· Личное сообщение · #16

Dr0p пишет:
Будущее за псевдокодом, это васико подобные языки.

хоть один твой прогноз относительно чего нибудь сбылся?
а то помнится не один ты смерть с/c++ пророчишь
оно то и понятно, тяжело что то новое освоить, не понимание как это работает, желание переделать и видеть свою логику в чужей.. ну итд)
пиши на асме, не надо тебе больше писать ничего на С




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 13:52
· Личное сообщение · #17

reversecode

Причём там освоить. Можно быть гуру в скрипте, но это не сделает его лучше.

> пиши на асме, не надо тебе больше писать ничего на С

А я и пишу на асме и скрипт не юзаю. Он для моих задач не подходит по большей части. Я давно над своим языком думаю.



Ранг: 2.6 (гость), 4thx
Активность: 0=0
Статус: Участник

Создано: 09 декабря 2013 13:56
· Личное сообщение · #18

Dr0p пишет:
Как по мне, так бессмысленное выражение. Функции нельзя присвоить значение.


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




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 09 декабря 2013 13:56
· Личное сообщение · #19

когда увидим драфт нового правильного языка? как он будет называться? возьмет ли инициалы создателя?



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 09 декабря 2013 14:04
· Личное сообщение · #20

Pelles C
Code:
  1. #include <stdio.h>
  2.  
  3. typedef void (__stdcall *BreakRef)(void);
  4.  
  5. static char BreakPoint[] = {0xCC};
  6.  
  7. int main (int argc, char **argv)
  8. {
  9.          puts("hello");
  10.          BreakRef BreakCall = (BreakRef)&BreakPoint[0];
  11.          BreakCall();
  12.          ((void (*)())(&BreakPoint[0]))();
  13.          return 0;
  14. }
  15.  

Code:
  1. .text:00401000.text:00401000 main      proc near               ; CODE XREF: start+92p
  2. .text:00401000                 push    offset aHello   ; "hello"
  3. .text:00401005                 call    puts
  4. .text:0040100A                 pop     ecx
  5. .text:0040100B                 call    loc_405000
  6. .text:00401010                 call    loc_405000
  7. .text:00401015                 xor     eax, eax
  8. .text:00401017                 retn
  9. .text:00401017 main      endp
  10. ...
  11. .data:00405000                 int     3


P.S. на вкус и/или цвет товарищей нет. Может и убог местами синтаксисом, НО во-первых позволяет все что угодно душе с приведением типов, во-вторых ты еще синтаксис шаблонов в С++ не видел наверное..




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 14:11
· Личное сообщение · #21

Veliant

А как оно вообще так может быть, дефейн после использования

Си же однопроходовый. Гцц и цл такое не проглотят.



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 09 декабря 2013 14:22
· Личное сообщение · #22

а где дефейн после использования? BreakPoint уже инициализирован. Просто развил идею AnTiDoD, выкинув еще и имя переменной.




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 14:31
· Личное сообщение · #23

Veliant

А ну да, точно.



Ранг: 3.6 (гость)
Активность: 0=0
Статус: Участник

Создано: 09 декабря 2013 14:35
· Личное сообщение · #24

ждем от инде порт аввм, вмбе, сайда и остальных "моторов" на линупсы под гцц, тогда действительно можно носить гордое название илиты.
хелоуворлд пропускается через strip -s и заметно худеет с 90к до 18кб, т.к. там отладочные символы вшиты




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 16:06 · Поправил: Dr0p
· Личное сообщение · #25

carpucio

Эти вещи не портабельны. Они привязаны к железу и оси(имеют прямой доступ к этим ресурсам). Поэтому и си для них не приемлим.



Ранг: 44.8 (посетитель), 19thx
Активность: 0.040
Статус: Участник

Создано: 09 декабря 2013 16:11
· Личное сообщение · #26

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




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 16:35
· Личное сообщение · #27

SegFault

Так а что там пилить то, дефейните массив c дампом и юзаете.

> устаревший асм шлак не нужен

Смешно.



Ранг: 44.8 (посетитель), 19thx
Активность: 0.040
Статус: Участник

Создано: 09 декабря 2013 16:40
· Личное сообщение · #28

конешно смешно
а вот были бы написаны эти движки на С, переход на х64 архитектуру был бы равен времени перекомпеляции. базовые принципы движков все равно везде одинаковы что на х86 что на х64
а вот асм шлак с х86 на х64 без полного переписывания вапще не перенести. но элите не понять




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 16:45 · Поправил: Dr0p
· Личное сообщение · #29

SegFault

Какой рекомпиляции. На разной архитектуре совершенно разный код бинарный. И разбор такого кода описать скриптом не получится, константы то разные хотя бы. Портировтаь можно обычный код, который только штатные средства использует, апишки дёргает. Э это нет.

> что на х86 что на х64

У нас активно юзается такая технологи, как стековая маршрутизация. По сути это опорный функционал. Даёшь в народ методу, как это сделать на x64 с её фастколами!?



Ранг: 44.8 (посетитель), 19thx
Активность: 0.040
Статус: Участник

Создано: 09 декабря 2013 16:56
· Личное сообщение · #30

Ясен хрен что код бинарный зависит от архитектуры, поэтому и придумали высокоуровневые языки чтобы сделать код одинаково работающим на х86 и х64.

>константы то разные хотя бы

Code:
  1. #if defined(_WIN64)
  2. #define ELITE_CONSTANT 666
  3. #define BLIAT_GPE_NE_RABOTAET_NA_X64 TRUE
  4. #elif 
  5. #define ELITE_CONSTANT 999
  6. #endif


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

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




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 09 декабря 2013 16:59
· Личное сообщение · #31

SegFault

Даже ваш корявый патч кода на x64 не заведётся, а свалит ось в синь из за PG. А это уже соверщенно иная реализация. Срацца ты начал я так полагаю после того, как не смог какой то мой мотор завести ?


<< . 1 . 2 . 3 . >>
 eXeL@B —› Программирование —› GCC и include
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати