Форум программистов, компьютерный форум CyberForum.ru

Как перенести параметры из ф-ции printf() в самодельную - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 81, средняя оценка - 4.83
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
04.06.2011, 09:22     Как перенести параметры из ф-ции printf() в самодельную #1
Ребят, подскажите как решить задачу.
Нужно перенести параметры функции printf() в самодельную ф-цию myfunk(). При условии если булева переменная Х==1. Если не равна 1, то не переносить.
Задача осложняется тем, что число параметров ф-ции может быть переменным.
Подскажите пожалуйста, буду очень признателен.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.06.2011, 09:22     Как перенести параметры из ф-ции printf() в самодельную
Посмотрите здесь:

как переделать с cout на printf ? C++
Как вывести printf для струкутры C++
Как реализована функция printf C++
C++ Как выделить слово в printf?
Передача ф-ции как параметра другой ф-ции C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
05.06.2011, 17:12     Как перенести параметры из ф-ции printf() в самодельную #81
Цитата Сообщение от Uklunok Посмотреть сообщение
Если и так работает нормально
Если работает - хорошо. Правда я в этой теме так и не увидел рабочего кода
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 17:17  [ТС]     Как перенести параметры из ф-ции printf() в самодельную #82
Он по ссылке, в посте номер 42
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
05.06.2011, 17:31     Как перенести параметры из ф-ции printf() в самодельную #83
Цитата Сообщение от Uklunok Посмотреть сообщение
Он по ссылке, в посте номер 42
Так это и есть собственная реализация printf'а. "Собственная" - это не значит, что лично ты её написал, это означает "не стандартная, не библиотечная"

Добавлено через 2 минуты
При этом надо понимать, что там описана весьма корявая непереносимая реализация, которая страдает тем же дефектом, что и примеры без va_arg из статьи ValeryLaptev
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 17:39  [ТС]     Как перенести параметры из ф-ции printf() в самодельную #84
А есть открытая библиотечная?
И что значит не переносимая?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
05.06.2011, 17:50     Как перенести параметры из ф-ции printf() в самодельную #85
Цитата Сообщение от Uklunok Посмотреть сообщение
А есть открытая библиотечная?
glibc

Цитата Сообщение от Uklunok Посмотреть сообщение
И что значит не переносимая?
На других платформах работать не будет

Добавлено через 1 минуту
Хотя наверно я не туда залез. Надо смотреть версию "WITH stdarg.h"
http://www.menie.org/georges/embedde...tf-stdarg.html
Это по крайней мере переносимым образом написана, но всё равно с ошибками
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
06.06.2011, 12:01  [ТС]     Как перенести параметры из ф-ции printf() в самодельную #86
Цитата Сообщение от Evg Посмотреть сообщение
http://www.menie.org/georges/embedde...tf-stdarg.html
Это по крайней мере переносимым образом написана, но всё равно с ошибками
Ну это она и есть. - которую я взял.

Ребят, не подскажите тут в строке замечание:
C
1
2
3
4
 for ( ; *string ; ++string) {
        [U][I] printchar (out, *string); [/I][/U] - тут!
        ++pc;
    }
Говорит следующее: [VinC.exe] : src\Runtime.c line 74: (warning) C1408 parameter number 2 type mismatch

Описание из справки:
Warning Description: parameter mismatch in redeclaration
A mismatch occurred between the parameters in a function's declaration or prototype and the parameters passed to a function in a call. May also occur when a mismatch in the count of the parameters occurs in a redeclaration.
Как убрать такое?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
06.06.2011, 12:05     Как перенести параметры из ф-ции printf() в самодельную #87
Uklunok, out - указатель на указатель?
*string - имеет тип char, а не int?
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
06.06.2011, 12:25  [ТС]     Как перенести параметры из ф-ции printf() в самодельную #88
C
1
static int prints(char **out, const char *string, int width, int pad)
Всё верно: out - указатель на указатель, string - char

И как быть? Никак?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
06.06.2011, 15:28     Как перенести параметры из ф-ции printf() в самодельную #89
Uklunok, Можно в int преобразовать *string)
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
08.06.2011, 11:04  [ТС]     Как перенести параметры из ф-ции printf() в самодельную #90
Ребята, кто знает? Скажите, почему следующий код не выводит строковый параметр:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
 
int DEBUG=1;
int my_printf(const char *fmt, ...)
{
    if(DEBUG == 0) return printf ("DEBUG = 0\n");
    else
    {
        va_list args;
        va_start(args, fmt);
    return printf(fmt,args);
    }
}
void main(void)
{
my_printf("String %s and %s\n", "here", "here!");
system("pause");
}
В результате выводится на экран: String @ and @
Там где @ - абракадабра), хочу "String here and here!"

Как быть? подскажите пожалуйста

Добавлено через 17 минут
Я лучше перефразирую свой вопрос:
Можно сделать так чтобы приведённый ниже код работал без макросов???:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdarg.h>
 
void my_printf(const char *format, ...) {
        va_list args;
 
 
        va_start(args, format);
        printf(format, args);
        va_end(args);
 
/* если убрать эту строку, то будет использоваться
 * библиотечный стандартный printf
*/
//#define USE_MY_PRINTF
 
 
#if defined USE_MY_PRINTF
#define projectname_print my_printf
#else
#define projectname_print printf
#endif
 
int main() {
        projectname_print("%d.%d %s", 10, 15, "TEST\n");
system("pause");
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
08.06.2011, 14:30     Как перенести параметры из ф-ции printf() в самодельную #91
Цитата Сообщение от Uklunok Посмотреть сообщение
Скажите, почему следующий код не выводит строковый параметр
Потому что после va_start'а надо ещё и va_arg вызывать. Чтобы достать сам аргумент. А va_start настраивает только место в стеке, откуда будут аргументы доставаться

Цитата Сообщение от Uklunok Посмотреть сообщение
Можно сделать так чтобы приведённый ниже код работал без макросов???
В общем случае - нет. Потому что в общем случае у тебя неизвестно какие параметры, а потому ты не сможешь использовать va_arg. Точнее сможешь, но это уже получится самодельная релизация printf'а

Добавлено через 24 минуты
В своё время тоже пришлось писать велосипеды для работы с dsp. Вот кастрированный ограниченный вариант printf'а. Внутри используется буфер фиксированного размера, так что ещё есть и такое ограничение. Код писался под 64-битную архитектуру, так что %ld и %lx, работающие с long'ами, печатали 64-битные значения. Это следует учесть тем, кто хочет модифицировать код под печать 64-битных значений в 32-битном режиме (вместо long надо использовать long long)

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdarg.h>
#include <stdlib.h>
 
#define write_string(fd,s) write (fd, s, sizeof (s))
 
static char*
ull2str (unsigned long long val, int radix)
{
  static char digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
                           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  static char buff[128];
  char *pdst = buff + sizeof(buff) - 1;
 
  if (radix < 2 || radix > 16)
    {
      write_string (2, "*** ull2str: Incorrect radix\n");
      abort ();
    }
 
  *pdst-- = 0;
  do
    {
      *pdst-- = digits[val % radix];
      val /= radix;
    }
  while (val != 0);
 
  return pdst + 1;
}
 
static char*
sll2str (long long val, int radix)
{
  static char buff[128];
  char *psrc, *pdst = buff;
 
  if (val >= 0)
    return ull2str (val, radix);
 
  if (val == 0x8000000000000000LL)
    {
      write_string (2, "*** sll2str: Min int64 not suppotred yet\n");
      abort ();
    }
 
  psrc = ull2str (-val, radix);
  *pdst++ = '-';
  do
    *pdst++ = *psrc;
  while (*psrc++ != 0);
 
  return buff;
}
 
void
printf (const char *fmt, ...)
{
  const char *psrc = fmt;
  char buff[1024], c, *pdst = buff;
  va_list va;
 
  va_start (va, fmt);
 
  while ((c = *psrc++) != 0)
    {
      if (c == '%')
        {
          int is_long = 0;
 
        Lbeg:
          switch ((c = *psrc++))
            {
              const char *str;
              unsigned long long ull;
              char cc, lbuff[64];
 
              case 's':
                str = va_arg (va, char*);
              L:
                while ((cc = *str++) != 0)
                  *pdst++ = cc;
                break;
 
              case 'x':
                if (is_long)
                  ull = va_arg (va, unsigned long);
                else
                  ull = va_arg (va, unsigned);
                str = ull2str (ull, 16);
                goto L;
 
              case 'u':
                if (is_long)
                  ull = va_arg (va, unsigned long);
                else
                  ull = va_arg (va, unsigned);
                str = ull2str (ull, 10);
                goto L;
 
              case 'd':
                if (is_long)
                  ull = va_arg (va, long);
                else
                  ull = va_arg (va, int);
                str = sll2str (ull, 10);
                goto L;
 
              case 'l':
                if (is_long)
                  {
                    write_string (2, "Incorrect printf format\n");
                    abort ();
                  }
                else
                  is_long = 1;
                goto Lbeg;
 
              default:
                write_string (2, "Incorrect printf format\n");
                abort ();
                break;
            }
        }
      else
        *pdst++ = c;
    }
 
  write (1, buff, pdst - buff);
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
28.05.2013, 21:03     Как перенести параметры из ф-ции printf() в самодельную #92
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Вот к сожалению у меня нет никакой возможности в настоящее время проверить этот все на другой архитектуре. Хотя сам работал на множестве архитектур.
А было бы действительно интересно посмотреть...
Я всё время забываю, что общедоступным является 64-битный режим на intel'е. Т.е. практически каждый желающий может попробовать запустить один и тот же код на двух разных архитектурах и, поковырявшись в коде, понять, что эта программа написана неправильно

Вот упрощённый и немного переделанный (замена double -> int) твой пример:

C
#include <stdio.h>
 
void func (int x1, ...)
{
  int x2, x3, x4;
  int *p = &x1;
 
  x2 = *(p + 1);
  x3 = *(p + 2);
  x4 = *(p + 3);
 
  printf ("x1 = %x\n", x1);
  printf ("x2 = %x\n", x2);
  printf ("x3 = %x\n", x3);
  printf ("x4 = %x\n", x4);
}
 
int main (void)
{
  func (0x11111111, 0x22222222, 0x33333333, 0x44444444);
  return 0;
}
И вот результаты исполнения:

Код
Intel Linux, 32-битный режим
x1 = 11111111
x2 = 22222222
x3 = 33333333
x4 = 44444444
Код
Intel Linux, 64-битный режим
x1 = 11111111
x2 = 0
x3 = 0
x4 = c068a9c
Код
SPARC Linux, 32-битный режим
x1 = 11111111
x2 = ffee59d4
x3 = ffee59dc
x4 = f7f18000
Код
SPARC Linux, 64-битный режим
x1 = 11111111
x2 = 0
x3 = 0
x4 = 0
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
28.05.2013, 21:34     Как перенести параметры из ф-ции printf() в самодельную #93
В IE-32e (тот, что все называют х86_64) другая конвенция вызовов. Там первые несколько аргументов (вроде 4, могу ошибаться) передаются на регистрах, НО при этом место в стеке под них как бы выделяется, но содержит мусор. Это сделано для какой-то будущей необходимости.
Вообще для меня это немного странно - как передавать аргументы это ж дело компилятора, а не режима работы процессора, но про то, что агрументы теперь передаются на регистрах, я прочитал как раз в описании IE-32e. При чем Windows и *nix используют разные регистры. Может разработчики компиляторов и процессоров как-то договорились, что такие-то регистры отводятся под аргументы.

Добавлено через 7 минут
А, разобрался. Просто появились новые конвенции, именуемые Microsoft x64 calling convention и System V AMD64 ABI, которые и используют компиляторы под х86_64. Вот.

upd.
я вообще в тему пишу? а то мне 10 страниц темы перечитывать влом)
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
28.05.2013, 21:42     Как перенести параметры из ф-ции printf() в самодельную #94
Цитата Сообщение от Kastaneda Посмотреть сообщение
Вообще для меня это немного странно - как передавать аргументы это ж дело компилятора, а не режима работы процессора
Компилятор работает строго в соответствии с программными соглашениями (ABI, calling convention). Программное соглашение - это свойство конкретного режима на конкретном процессоре (и, может быть, на конкретной ОС). И для intel'а, и для sparc'а программные соглашения в режимах 32 и 64 отличаются друг от друга. Программные соглашения intel'а и sparc'а - и подавно отличаются.

В статье ValeryLaptev'а (Как перенести параметры из ф-ции printf() в самодельную) делается ошибочное предположение, что правила передачи параметров - это свойство языка Си. Скорее всего, это было почерпано из неправильных книжек, авторы которых не знают о том, что помимо i386 в миро много всяких разных процессоров. Статья описана в предположении, что все параметры передаются на стеке друг за другом. Но даже и в этом случае можно найти изъян - как только мы будем использовать короткие типы (char или short), мы увидим, что даже на i386 программа перестанет работать

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
я вообще в тему пишу? а то мне 10 страниц темы перечитывать влом)
Условно мы оба пишем не в тему. Но тут тесно переплелись две темы. Выделить одну из другой проблематично. Если пойдёт дальнейшее долгое обсуждение, то хвост можно будет отрезать в отдельную тему, но надо будет аккуратно ссылки на базовые посты воткнуть

Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
28.05.2013, 21:43     Как перенести параметры из ф-ции printf() в самодельную #95
Цитата Сообщение от Evg Посмотреть сообщение
Компилятор работает строго в соответствии с программными соглашениями (ABI, calling convention). Программное соглашение - это свойство конкретного режима на конкретном процессоре.
Не совсем въехал. Мы же можем для интела х86 использовать конвенции cdecl, pascal, stdcall и т.д., при том, что все они отличаются. Компилятор знает как с ними работать и генерит соответствующий код. Почему это сводится к свойствам конкретного режима (допустим про разные процессоры сейчас не говорим) ?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
28.05.2013, 21:46     Как перенести параметры из ф-ции printf() в самодельную #96
Цитата Сообщение от Kastaneda Посмотреть сообщение
Не совсем въехал. Мы же можем для интела х86 использовать конвенции cdecl, pascal, stdcall и т.д., при том, что все они отличаются. Компилятор знает как с ними работать и генерит соответствующий код. Почему это сводится к свойствам конкретного режима (допустим про разные процессоры сейчас не говорим) ?
Да, действительно, есть ещё и такие нанотехнологии. Но это уже НЕдефолтные, а явно задаваемые пользователем. Ну суть остаётся та же самая - правила передачи параметров диктует некоторая машинно-зависимая спецификация, а не стандарт языка. Любое предположение о том, что параметры передаются некоторым конкретным способом, делает программу непереносимой (хотя и корректной в рамках конкретного программного соглашения)
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
28.05.2013, 21:52     Как перенести параметры из ф-ции printf() в самодельную #97
Ну т.е. я знаю, что бывает такое - разработчики процессора говорят: "мы отдаем вам (программистам) 4 регистра, вы можете использовать их для передачи параметров в функции, мы задокументируем это".
Это понятно, но вот в случае с передачей аргументов на стеке непонятно, при чем тут режим процессора, если стек одинаково работает в любых режимах (ну допустим) ?

upd.
Цитата Сообщение от Kastaneda Посмотреть сообщение
(программистам)
читай "разработчикам компиляторов".

Добавлено через 4 минуты
Цитата Сообщение от Evg Посмотреть сообщение
правила передачи параметров диктует некоторая машинно-зависимая спецификация, а не стандарт языка.
Ок, почему тогда сейчас (в х86_64) мы имеем 2 правила передачи параметров - для Windows и System V? и отличаются они лишь используемыми регистрами и организацией стека. Тут совсем не понятно, это ж просто разные ОС для одного режима одного процессора. Получается ноги растут из компиляторов?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
29.05.2013, 15:49     Как перенести параметры из ф-ции printf() в самодельную #98
Цитата Сообщение от Kastaneda Посмотреть сообщение
Это понятно, но вот в случае с передачей аргументов на стеке непонятно, при чем тут режим процессора, если стек одинаково работает в любых режимах (ну допустим) ?
Передача параметров обычно описывается через слоты. Т.е. описывается положение слотов на регистрах/памяти, а далее описывается, как значения укладываются в слоты. По тем машинам, программные соглашения которых мне доводилось читать, размер слота может быть либо 4, либо 8 байт (как правило, в зависимости от размера аппаратного регистра).

Если копнуть дальше, то есть ещё тонкости. На SPARC в режиме 64 размер слота равен 8 байт. Если мы передаём параметр типа int, то он кладётся в младшую часть слота (left justify), а если передаём структуру, состоящую из одного int'а - то в старшую часть слота (right justify). Может быть, я перепутал лево и право (на память не помню), но не суть. Смысл в том, что параметр одного и того же размера на одной и той же позиции (типа 7-й по счёту параметр) может оказаться в разных местах стека

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
Ок, почему тогда сейчас (в х86_64) мы имеем 2 правила передачи параметров - для Windows и System V? и отличаются они лишь используемыми регистрами и организацией стека. Тут совсем не понятно, это ж просто разные ОС для одного режима одного процессора. Получается ноги растут из компиляторов?
На вопрос "почему" я ответить не могу - это надо спрашивать у тех, кто это придумал. Я здесь говорю лишь о том, что программные соглашения НЕ являются частью языка программирования. Кто конкретно их придумывает (разработчики железа или софта) я тоже однозначно ответить не могу. Скорее всего, это как-то решается в комплексе совместными усилиями. В современном мире всё-таки разработка аппаратуры ведётся опираясь на возможности компилятора

Добавлено через 17 часов 49 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
но вот в случае с передачей аргументов на стеке непонятно, при чем тут режим процессора, если стек одинаково работает в любых режимах (ну допустим) ?
Для наглядной демонстрации этого момента немного перепишем пример: добавим 8 фиктивных параметров, которые заполнят всю регистровую часть и интересующие нас параметры будут все в стеке. По полученным результатам хорошо видны те слоты, о которых я писал выше

C
#include <stdio.h>
 
void func (int fake0, int fake1, int fake2, int fake3,
           int fake4, int fake5, int fake6, int fake7,
           int x1, ...)
{
  int x2, x3, x4;
  int *p = &x1;
 
  x2 = *(p + 1);
  x3 = *(p + 2);
  x4 = *(p + 3);
 
  printf ("x1 = %x\n", x1);
  printf ("x2 = %x\n", x2);
  printf ("x3 = %x\n", x3);
  printf ("x4 = %x\n", x4);
}
 
int main (void)
{
  func (0, 0, 0, 0, 0, 0, 0, 0,
        0x11111111, 0x22222222, 0x33333333, 0x44444444);
  return 0;
}
Код
Intel Linux, 32-битный режим
x1 = 11111111
x2 = 22222222
x3 = 33333333
x4 = 44444444
Код
Intel Linux, 64-битный режим
x1 = 11111111
x2 = 0
x3 = 22222222
x4 = 0
Код
SPARC Linux, 32-битный режим
x1 = 11111111
x2 = 22222222
x3 = 33333333
x4 = 44444444
Код
SPARC Linux, 64-битный режим
x1 = 11111111
x2 = 0
x3 = 22222222
x4 = 0
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
29.05.2013, 17:17     Как перенести параметры из ф-ции printf() в самодельную #99
Цитата Сообщение от Evg Посмотреть сообщение
По полученным результатам хорошо видны те слоты, о которых я писал выше
Конкретно в данном случае (Linux 64) думаю дело в другом. Дело в том, что в long mode нет команды, которая толкает в стек 32 бита, т.е. если написать
Assembler
1
push eax
то будет ошибка компиляции. Так уж устроен этот режим, что в стек можно толкнуть только 16 или 64 бита. Поэтому при передаче аргументов на стеке int просто "расширился" до 64 бит, поэтому мы видим нули в х2 и х4.
Думаю вот так мы увидим то, что хотели
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void func (int fake0, int fake1, int fake2, int fake3,
           int fake4, int fake5, int fake6, int fake7,
           int x1, ...)
{
  int x2, x3, x4;
  int *p = &x1;
 
  x2 = *(p + 2);
  x3 = *(p + 4);
  x4 = *(p + 6);
 
  printf ("x1 = %x\n", x1);
  printf ("x2 = %x\n", x2);
  printf ("x3 = %x\n", x3);
  printf ("x4 = %x\n", x4);
}
сейчас сижу под 32 битной виндой, поэтому не могу проверить.

Цитата Сообщение от Evg Посмотреть сообщение
хорошо видны те слоты
Не уверен, что правильно понял смысл слова "слот". Может это то, про что я написал выше? Мне кажется это немного другое.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.05.2013, 22:02     Как перенести параметры из ф-ции printf() в самодельную
Еще ссылки по теме:

Калькулятор на Си. Как реализовать триногометрические ф-ции и функцию логарифм? C++
Чем ::printf предпочтительнее printf? C++
C++ Параметры printf

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
29.05.2013, 22:02     Как перенести параметры из ф-ции printf() в самодельную #100
Цитата Сообщение от Kastaneda Посмотреть сообщение
Не уверен, что правильно понял смысл слова "слот". Может это то, про что я написал выше? Мне кажется это немного другое
В типовых программных соглашениях любая передача параметров идёт по границам слота. Возьмём крайний случай (как это есть на i386), когда на машине вся передача параметров идёт через стек. На i386 в этом случае вся стековая область делится на смежные куски по 4 байта, называемые слотами. Любой параметр занимает минимум 1 слот. Если нам надо передать 4 байта, то они на счёт слотов растянутся в памяти на 16 байт (а не на 4, как могло бы показаться на первый взгляд).

Когда есть передача параметров через регистры, стратегия получается примерно такой, что слот N1 лежит на регистре, слот N2 лежит на следующем регистре, ...., слот NX лежит в стеке и т.п. Именно такую ситуацию мы видим в тесте из поста #92 (где у i386 все слоты стековые, а на остальных машинах используются регистры).

На 64-битных архитектурах размер слота, как правило, равен 8 байтам, а не 4. И это связано в первую очередь с размером регистра, а вовсе не с тем, что на x86-64 какие-то кривые операции записи в память

Я попытаюсь в инете найти документ, который у меня в бумажном виде есть. Там по картинке более-менее понятно станет

Добавлено через 4 часа 15 минут
Нашёл
https://www.google.ru/url?sa=t&rct=j...,d.bGE&cad=rja
Раздел 3.2.2. Одна строка таблицы соответствует одному "слоту"
Yandex
Объявления
29.05.2013, 22:02     Как перенести параметры из ф-ции printf() в самодельную
Ответ Создать тему
Опции темы

Текущее время: 11:44. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru