Сейчас на форуме: zombi-vadim, zds (+4 невидимых) |
![]() |
eXeL@B —› Программирование —› GCC и include |
<< . 1 . 2 . 3 . >> |
Посл.ответ | Сообщение |
|
Создано: 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 ![]() |
|
Создано: 09 декабря 2013 02:20 · Личное сообщение · #2 |
|
Создано: 09 декабря 2013 02:39 · Личное сообщение · #3 reversecode пишет: вопросы к тем кто его собирал (компиль) Еще такое дело, он собирал в 4.8+, а так есть такая шляпа, как быстрая сборка, никакой оптимизации, собирается абы запустилось, но быстрооо. Еще там за каким то иксом инфа о фреймах, сапшены.. код унылый, но безопасный, аж жуть берет и это на одну строчку кода. ![]() ![]() |
|
Создано: 09 декабря 2013 02:40 · Поправил: dosprog · Личное сообщение · #4 Dr0p, да нормально всё с Си. Только вот с примером брейка неясно : char BreakPoint[]={ /* массив байтов в сегменте данных. Лежит <int 3>, должно ещё лежать <retn> */ 0xCC /* тут ещё ",0xC3" , если это будет WIN32-PE */ }; Вот для такого-то и лучше применять inline assembler. Хотя в примере - переносимый код для любого компилятора. Красиво. А вообще, во многих реализациях есть директива типа __emit__(0xCC), для вставки байтов прямо в код. Удобно, но некрасиво и непереносимо. ![]() |
|
Создано: 09 декабря 2013 03:06 · Личное сообщение · #5 |
|
Создано: 09 декабря 2013 03:07 · Поправил: reversecode · Личное сообщение · #6 |
|
Создано: 09 декабря 2013 03:10 · Личное сообщение · #7 |
|
Создано: 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(), вывалилось бы несколько ошибок компиляции. Что тут ещё предположить... За такие "штучки" людям и нравится язык Си. ![]() |
|
Создано: 09 декабря 2013 04:13 · Личное сообщение · #9 |
|
Создано: 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 Использование переменной вообще теряет всякий смысл. Но компиль всё равно выделяет её в локалях. Я это вообще понять не могу. За такие "штучки" людям и не нравится язык Си. ![]() |
|
Создано: 09 декабря 2013 06:54 · Личное сообщение · #11 |
|
Создано: 09 декабря 2013 07:50 · Поправил: dosprog · Личное сообщение · #12 Dr0p, захотели регистровую переменную - и получили register BreakRef BreakCall...: mov ebx,0x404000 call ebx Зато теперь можно давать подряд сколько угодно: call ebx ........ call ebx ........ call ebx ........ - оптимизация Ну, а издержки-то будут по-любому. На асме можно сделать что угодно, но жизнь коротка... Я стараюсь не применять такую оптимизацию (как это <call ebx>) , а на Си - почему бы и не загадать "register"? ![]() |
|
Создано: 09 декабря 2013 10:00 · Личное сообщение · #13 |
|
Создано: 09 декабря 2013 13:16 · Личное сообщение · #14 |
|
Создано: 09 декабря 2013 13:45 · Поправил: Dr0p · Личное сообщение · #15 dosprog > почему бы и не загадать "register"? Потому что нужно гадать. Танцы с бубном. Во что оно скомпилится известно только тем двум барадатым дядькам. AnTiDoD Как по мне, так бессмысленное выражение. Функции нельзя присвоить значение. SegFault Что собстно смешного ? У него множество диалектов, что один компиль съедает, другой выдаст фейл. Некоторые считают компиль чуть ли не святым граалем". Си это тупиковая ветвь в компиляции. Развилось оно в ооп костыли, это только усложнило коденг. Будущее за псевдокодом, это васико подобные языки. Они максимально краткие и близкие к псевдокоду. Взять такую область, как метаморфизм. Никому на ум не придёт генерить сишный скрипт. Потому что он более громоздкий, чем конечный бинарнуй код. ![]() |
|
Создано: 09 декабря 2013 13:49 · Личное сообщение · #16 Dr0p пишет: Будущее за псевдокодом, это васико подобные языки. хоть один твой прогноз относительно чего нибудь сбылся? а то помнится не один ты смерть с/c++ пророчишь ![]() оно то и понятно, тяжело что то новое освоить, не понимание как это работает, желание переделать и видеть свою логику в чужей.. ну итд) пиши на асме, не надо тебе больше писать ничего на С ![]() |
|
Создано: 09 декабря 2013 13:52 · Личное сообщение · #17 |
|
Создано: 09 декабря 2013 13:56 · Личное сообщение · #18 |
|
Создано: 09 декабря 2013 13:56 · Личное сообщение · #19 |
|
Создано: 09 декабря 2013 14:04 · Личное сообщение · #20 Pelles C Code:
Code:
P.S. на вкус и/или цвет товарищей нет. Может и убог местами синтаксисом, НО во-первых позволяет все что угодно душе с приведением типов, во-вторых ты еще синтаксис шаблонов в С++ не видел наверное.. ![]() |
|
Создано: 09 декабря 2013 14:11 · Личное сообщение · #21 |
|
Создано: 09 декабря 2013 14:22 · Личное сообщение · #22 |
|
Создано: 09 декабря 2013 14:31 · Личное сообщение · #23 |
|
Создано: 09 декабря 2013 14:35 · Личное сообщение · #24 |
|
Создано: 09 декабря 2013 16:06 · Поправил: Dr0p · Личное сообщение · #25 |
|
Создано: 09 декабря 2013 16:11 · Личное сообщение · #26 |
|
Создано: 09 декабря 2013 16:35 · Личное сообщение · #27 |
|
Создано: 09 декабря 2013 16:40 · Личное сообщение · #28 |
|
Создано: 09 декабря 2013 16:45 · Поправил: Dr0p · Личное сообщение · #29 SegFault Какой рекомпиляции. На разной архитектуре совершенно разный код бинарный. И разбор такого кода описать скриптом не получится, константы то разные хотя бы. Портировтаь можно обычный код, который только штатные средства использует, апишки дёргает. Э это нет. > что на х86 что на х64 У нас активно юзается такая технологи, как стековая маршрутизация. По сути это опорный функционал. Даёшь в народ методу, как это сделать на x64 с её фастколами!? ![]() ![]() |
|
Создано: 09 декабря 2013 16:56 · Личное сообщение · #30 Ясен хрен что код бинарный зависит от архитектуры, поэтому и придумали высокоуровневые языки чтобы сделать код одинаково работающим на х86 и х64. >константы то разные хотя бы Code:
>Портировтаь можно обычный код любой код можно портировать если он не привязан жестко к архитектуре или среде а если движки привязаны к среде то значит шлаковые движки, нужно отвязать ![]() |
|
Создано: 09 декабря 2013 16:59 · Личное сообщение · #31 |
<< . 1 . 2 . 3 . >> |
![]() |
eXeL@B —› Программирование —› GCC и include |