1

Тема: Функції зі змінною кількістю параметрів

Вітаю! Почав вчити поглибленіше функції в С++, і ось ніяк не можу зрозуміти поняття "вказівник, параметр, індекс/ярлик".

#include<iostream>
using namespace std;
int sum(int k, ...){
    int *p = &k; //налаштували вказівник на параметр k
    int s=0;
    for (k ; k!=0; k--){
        cout<<"k = "<<k<<"  p = "<<*p<<endl;
        s+=*(++p);
    }
    return s;
}
int main( ){
    cout<< sum(4, 1, 2, 3, 4)<<endl;
}

Ось код, по ідеї він повинен додавати n чисел (перше число в функції), проте як я бачу щось моєму p стало погано і через це замість суми 4,3,2,1 воно додає дивні числа. Допоможіть будь ласка розібратись :)

Подякували: mamkin haker, koala2

2 Востаннє редагувалося mamkin haker (29.10.2021 07:08:02)

Re: Функції зі змінною кількістю параметрів

#include <iostream>

int sum (int k, ...)
{
  int *p = &k;
  int s = 0;
  for (k; k != 0; k--)
    {
      std::cout << "k = " << k << "  p = " << *p << std::endl;
      s += *(p);
    }
  return s;
}

int main ()
{
  std::cout << sum (4, 1, 2, 3, 4) << std::endl;
}
//out

k = 4  p = 4
k = 3  p = 3
k = 2  p = 2
k = 1  p = 1
10

навіщо ви до вказівника додаєте 1??
тримайте https://msn.khnu.km.ua/pluginfile.php/4 … 2/Lab3.pdf

Подякували: SkilLock1

3

Re: Функції зі змінною кількістю параметрів

Бо угода про виклики в сучасних компіляторах не використовує стек для перших кількох аргументів. Вам треба проголосити функцію як cdecl, щоб так працювати зі стеком (як саме - залежить від вашого компілятора). І взагалі вручну перебирати стек - то не добре, є заголовок <cstdarg>/<stdarg.h> саме для того, щоб уникати усіх двозначностей на різних компіляторах.

mamkin haker написав:

навіщо ви до вказівника додаєте 1??

Бо ви гадки не маєте про те, що означають ... в проголошенні функції.

Подякували: mamkin haker, Betterthanyou, SkilLock, leofun014

4

Re: Функції зі змінною кількістю параметрів

koala написав:
mamkin haker написав:

навіщо ви до вказівника додаєте 1??

Бо ви гадки не маєте про те, що означають ... в проголошенні функції.

можете скинути де про це можна почитати?
ато я уявлення не маю як це знайти в пошуковику

5 Востаннє редагувалося mamkin haker (29.10.2021 10:08:31)

Re: Функції зі змінною кількістю параметрів

мої думки
/*
*ааа я зрозумів,
*k - кількість елементів
*... - решта елементів
*/

p++ потрібно для того щоб взявся новий елемент?

6

Re: Функції зі змінною кількістю параметрів

koala написав:

Бо угода про виклики в сучасних компіляторах не використовує стек для перших кількох аргументів.

Залежить від.
Я б сформулював "бо щодо використання регістрів та стеку для аргументів  в сучасних компіляторах треба дивитися угоду про виклики".
Бо зустрічав варіант, коли в регістри може напхатися купа аргументів на загальну суму байтів (а не штук аргументів) ± вирівнювання і лише потім стек, але якщо функція має змінну кількість аргументів, то всі аргументи передаються через стек.

Подякували: ch0r_t, wander2

7 Востаннє редагувалося ReAl (29.10.2021 10:14:54)

Re: Функції зі змінною кількістю параметрів

mamkin haker написав:

можете скинути де про це можна почитати?
ато я уявлення не маю як це знайти в пошуковику

ellipsis (так називаються ті три крапкиin programming

Подякували: mamkin haker, leofun012

8 Востаннє редагувалося koala (29.10.2021 10:37:19)

Re: Функції зі змінною кількістю параметрів

ReAl написав:

але якщо функція має змінну кількість аргументів, то всі аргументи передаються через стек.

Це і зветься "угодою про виклики".
А ще бувають обфускації стеку, особливо на онлайн-компіляторах.

mamkin haker написав:

можете скинути де про це можна почитати?

У підручнику.
Ну або ж https://studfile.net/preview/5206428/page:2/ - схоже, пан SkilLock з чогось такого і брав інформацію. Також https://en.cppreference.com/w/cpp/utility/variadic (англ.)

Подякували: mamkin haker, Chemist-i, SkilLock, leofun014

9

Re: Функції зі змінною кількістю параметрів

koala написав:
ReAl написав:

але якщо функція має змінну кількість аргументів, то всі аргументи передаються через стек.

Це і зветься "угодою про виклики".

Я знаю.
Відповідав на виділене:

koala написав:

Бо угода про виклики в сучасних компіляторах не використовує стек для перших кількох аргументів.

і писав про те, що це далеко не завжди так саме по ABI, за умовчанням, без жодних отих cdecl.

Подякували: wander, ch0r_t2

10

Re: Функції зі змінною кількістю параметрів

Але конкретно тут, схоже, саме так.

11

Re: Функції зі змінною кількістю параметрів

Гм, десь я вже цей код бачив, правда він був трохи більш схожим на робочий. По пам'яті, воно б десь так мало виглядати:

#ifdef _MSC_VER
#    define __noinline __declspec(noinline)
#    define __cdecl __cdecl
#else
#    define __noinline __attribute__((noinline))
#    define __cdecl __attribute__((__cdecl__))
#endif
 
__noinline int __cdecl sum(int k, ...) {
    int result = 0;
    for (int* p_arg = &k; k > 0; k--) {
        result += *(++p_arg);
    }
    return result;
}

// ...
sum(4, 1, 2, 3, 4);
sum(5, 11, 12, 13, 14, 15);
Прихований текст

clang++ -m32 -O0 -o main main.cpp
./main
10
65

Ну і так, це UB. Ніхто нікому нічого не винен :)

12

Re: Функції зі змінною кількістю параметрів

Ви всі якісь хворі, якщо забуваєте про va_arg.

13

Re: Функції зі змінною кількістю параметрів

0xDADA11C7 написав:

Ви всі якісь хворі, якщо забуваєте про va_arg.

Ви якісь хворі, коли не використовуєте C++ vector.

14

Re: Функції зі змінною кількістю параметрів

Перепрошую, а нащо ж я stdarg.h згадував?

Подякували: 0xDADA11C71

15

Re: Функції зі змінною кількістю параметрів

tchort написав:
0xDADA11C7 написав:

Ви всі якісь хворі, якщо забуваєте про va_arg.

Ви якісь хворі, коли не використовуєте C++ vector.

Ви якісь хворі, коли не використовуєте variadic templates.

Подякували: Betterthanyou1

16

Re: Функції зі змінною кількістю параметрів

Прихований текст

Fuck variadic`s templates

17

Re: Функції зі змінною кількістю параметрів

Ви якісь хворі, якщо ви

tchort написав:
Прихований текст

Fuck variadic`s templates

замість дівчат

Подякували: ch0r_t1

18

Re: Функції зі змінною кількістю параметрів

Прихований текст

Разом.

19

Re: Функції зі змінною кількістю параметрів

Бо угода про виклики в сучасних компіляторах не використовує стек для перших кількох аргументів.

для koala

Пане koala, що з вами? Ви не виспалися? Травма на виробництві? Начальник нагримав?

Бо угода про виклики в сучасних компіляторах

Яка саме угода для якого процесора? Для х86 є stdcall (використовує стек для всіх аргументів) та сcall (використовує стек для всіх аргументів), існує ще якийсь fastcall але я його в очі не бачив, тому ним можна знехтувати.
Для х64 є єдина угода про виклики, де перші аргументи передаються в регістрах процесора, але під них все одно резервується стек і, за потреби, ці аргументи туди записуються.

20

Re: Функції зі змінною кількістю параметрів

koala написав:
ReAl написав:

але якщо функція має змінну кількість аргументів, то всі аргументи передаються через стек.

Це і зветься "угодою про виклики".
А ще бувають обфускації стеку, особливо на онлайн-компіляторах.

mamkin haker написав:

можете скинути де про це можна почитати?

У підручнику.
Ну або ж https://studfile.net/preview/5206428/page:2/ - схоже, пан SkilLock з чогось такого і брав інформацію. Також https://en.cppreference.com/w/cpp/utility/variadic (англ.)

Ну це ВНС, це Львівська Політехніка 8)
Теорію перечитав, дякую, але повертаючись до мого коду: начебто все правильно написав, але вперто не бачу помилки :/