c ++ va_arg типографская ошибка - PullRequest
2 голосов
/ 29 декабря 2010

All

Я пишу небольшое приложение на С ++, и эта проблема была озадачена. Есть ли способ создать (и позже перехватить) ошибку при доступе к элементу из макроса va_list, используя va_arg, если тип элемента не ожидается. Например: -

count=va_arg(argp,int); 
if (count <= 0 || count > 30)
{   
      reportParamError();   return;
}

Теперь, если я передаю typedef вместо int, я получаю мусорное значение на компиляторе MS, но 95% отсчета времени получает значение 0 на gcc (на 64-битной sles10 sys). Есть ли способ, которым я могу принудительно провести некоторую проверку типов, чтобы получить ошибку, которая может быть перехвачена в блоке перехвата?

Любые идеи по этому поводу были бы очень полезны для меня. Или есть лучший способ сделать это. Прототип функции: -

 void process(App_Context * pActx, ...) 

Функция называется

 process(pAtctx,3,type1,type2,type3);

Важно, чтобы pActx передавался как 1-й параметр и, следовательно, не мог передавать счет как 1-й параметр.


Update-1

Хорошо, это звучит странно, но nargs не является частью va_list на sles10 gcc. Я должен был положить в

#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif

После этого параметры, следующие за nargs, не получают значения мусора. Тем не менее, это вводит компилятор / платформу на основе #ifdefs .... Спасибо Крис и Кристофер

Ответы [ 2 ]

5 голосов
/ 29 декабря 2010

Если вы знаете, что счет всегда будет передаваться в качестве второго аргумента, вы всегда можете изменить подпись следующим образом:

void process(App_Context * pActx, int count, ...) 

Если это не вариант, то на самом деле нет способа его поймать. Вот как работает список переменных-аргументов-списков: вызывающий не может узнать, какие передаваемые аргументы, кроме той информации, которую передает вызывающий.

Если вы посмотрите, как реализован макрос va_arg и связанные с ним макросы, вы сможете выяснить, как проверить все содержимое стека. Однако это не будет переносимым и не рекомендуется, кроме как в качестве средства отладки.

Возможно, вы захотите рассмотреть альтернативы переменным-аргументам, такие как перегрузка функций, шаблоны или передача vector или list аргументов.

2 голосов
/ 29 декабря 2010

Нет, нет пути.varargs не предоставляет никаких способов проверки типов передаваемых параметров. Вы должны читать их только с правильным типом, что означает, что вам нужен другой способ передачи информации о типах.

Скорее всего, вам лучшеизбегая функциональности varargs, если она вам действительно не нужна.Это действительно функция C ++ только для унаследованных функций, таких как printf и друзья.

...