Тонкости C/C++

Тема в разделе "LANGS.C", создана пользователем Nafanya, 5 фев 2011.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel

    Глянул несколько примерчиков, так ведь все равно используется один именной параметр.
    Код (Text):
    1. void __cdecl funct(int cnt, ...)
    2. {
    3.     va_list vl;
    4.     va_start(vl, cnt);
    5.  
    6.     for(int i = 0; i != cnt; i++)
    7.     {
    8.         std::string& str = va_arg(vl, std::string);
    9.         printf("str = %s\n", str.c_str());
    10.     }
    11.  
    12.     va_end(vl);
    13. }
    А как без именного параметра (и без ассемблера) к аргументам в теле функции обратиться? Можете примерчик привести?

    Код (Text):
    1. func ()
    2. {
    3. //Как обратиться к аргументам?
    4. }
    5.  
    6. int main(void)
    7. {
    8. func (3,4,5,6);
    9. return(0);
    10. }
     
  2. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    "при cdecl" - точнее говоря при том соглашении вызова, при котором вызывающий сам чистит стек

    хотя в теории возможен код "pop edx / add esp, n / jmp edx" вместо "ret n"
     
  3. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    например так: _AddressOfReturnAddress даст вам указатель на адрес возврата на стеке, параметры лежат рядышком...
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Nafanya в С++
    Код (Text):
    1. #include <intrin.h>
    2.  
    3. va_start(va, *_AddressOfReturnAddress());
    --
    на 2 сек опоздал =)
     
  5. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    ну внутри функции можно рассчитать, насколько стек нужно подчистить, но не понятно пока, как реализовать без асм-вставок)

    бывает)
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    в басике тоже есть переменное число параметров, и вроде там не cdecl
    как там организуется?
     
  7. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Блин, ну я же просил почитать примеры моего кода и изучить конвенции вызовов, cdecl, в частности... Держите пример работы с функцией вообще без формальных аргументов на си, раз Вы этого так желаете.

    Код (Text):
    1. #include <stdio.h>
    2. int func()
    3. {
    4. #ifdef _MSC_VER
    5.     int* stack;
    6.     _asm
    7.     {
    8.         mov stack, ebp
    9.     }
    10. #else
    11.     static int* stack __asm("sstack");
    12.  
    13.     __asm("mov %ebp, sstack;");
    14. #endif
    15.  
    16.     return *(stack + 2) + *(stack + 3);
    17. }
    18.  
    19. int main(void)
    20. {
    21.     int a = 2, b = 3;
    22.  
    23.     printf("%u + %u = %u", a, b, func(a, b));
    24.  
    25.     return 0;
    26. }
    Работает в ms visual studio и dev cpp, и похоже, что на линухе тоже: http://codepad.org/E69lGkop
    Пролог у функций везде одинаков: push ebp; mov ebp, esp.

    Хотя вижу Вам тут решение уже предложили, хотя _AddressOfReturnAddress это Microsoft-specific :)
     
  8. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    в басике? в компилируемом басике это есть? про интерпретируемые языки вопросов вообще не должно быть, так как там свой байт-код, в котором может быть все, что угодно...

    вы бы сделали действительно переменное число параметров)) и кстати на x64 работать не будет)))
     
  9. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    GRRRLPower

    Сильно конечно! А Вы можете сделать тот же простой пример без асм вставок - чистым сишняком? Интересно взглянуть-как это будет выглядеть. Или это unreal:)
     
  10. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Ради примера передал два параметра, а по сути разницы нет. У меня на x64 висте работает.
     
  11. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Си фиолетово на кол-во параметров и их типы, в общем ассемблер. Можно объявить функцию с одним параметром, а передать десять. Объявить тип int, а передать что угодно другое. Но только должен быть _cdecl конечно. Даже и объявлять в Си необязательно, линковщик найдёт и прилинкует без посторонней помощи.
     
  12. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    _cdecl скорее, с _stdcall произвольное число аргументов не прокатит, я выше пару примеров приводил уже...
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    а да... я чет не увидел * после инта) первая мысль... но как может x64 нормально работать с ebp, а не rbp? вы видимо 32-битный бинарник собираете и запускаете в WOW64...

    я тебе недавно сказал, как обойтись без асм-вставки... но на gcc нужно добавлять интрин, в стандартной пачке не обойтись наверное... в студии есть _AddressOfReturnAddress...
     
  14. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    GRRRLPower
    Да, конечно, описочка вышла, поправился.
     
  15. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Вообще Си оно и есть Си, типобезопасность почти как у ассемблера.
     
  16. newbie

    newbie New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2008
    Сообщения:
    1.246
    :lol: жесть
    Чё нафаня, много заказов уже принял? :lol:
     
  17. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    newbie

    Весь стол завален, никак не разгребу:) Тебя в помощники наверно найму скоро:)
     
  18. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Да, так и есть. На самом деле, мне неизвестны x64-компиляторы, которые бы директиву __asm поддерживали :)
    MSVC, например, не поддерживает в x64-режиме.
     
  19. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    С++ тоже допускает подобные ф-ции:
    Код (Text):
    1. int func(...);
    Переносимого способа получить параметры такой ф-ции нет.
     
  20. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    возможно использовать любой сторонний асм-компилятор (я юзаю yasm) и делать inline функции... по сути тоже самое, что и асм вставка... вообще интрин-функции в msvc так и сделаны... и я думал, что mingw-w64 поддерживает асм вставки, хотя я никогда ее не использовал... и интрин функции там есть вроде...

    ADD: посмотрел интрин-функции в mingw-w64, там нет _AddressOfReturnAddress... и все интрин-функции сделаны асм-вставками, в них похоже не участвуют специфичные для x64 команды... довольно странно))