Поскольку я нашел это во время поиска в Google, вы должны знать, что этого простого правила достаточно, чтобы предотвратить это сообщение:
react/jsx-uses-react
Набор правил react/recommended
добавляет многие другие правила вы можете не захотеть.
В зависимости от компилятора, что такое тип va_list, каковы макросы va_start и va_end. Вы не можете сделать это стандартным способом. Вам нужно будет использовать конструкцию, специфичную для компилятора.
Возможно, вы можете изменить функцию foo? Если это так, то сделайте это обратно - конвертируйте va_list в QList и сделайте «foo» принять QList.
// EDIT
Затем посмотрите, что такое тип va_list, что va_start и va_end макросы находятся в вашем конкретном компиляторе. Затем создайте свой va_list таким образом, чтобы эти макросы работали над ним.
Если количество элементов в списке ограничено, я бы пошел на ручную отправку в зависимости от количества элементов.
void call_foo(int count, ...) {
va_list args;
va_start(args, count);
foo(count, args);
va_end(args);
}
switch (contacts.count()) {
case 0: return call_foo(contacts.count());
case 1: return call_foo(contacts.count(),
contacts.at(0)->getName());
case 2: return call_foo(contacts.count(),
contacts.at(0)->getName(),
contacts.at(1)->getName());
case 3: return call_foo(contacts.count(),
contacts.at(0)->getName(),
contacts.at(1)->getName(),
contacts.at(2)->getName());
default: /* ERROR HERE, ADD MORE CASES */ return call_foo(0);
}
То, что вы пытаетесь использовать, - alloca
. Объект va_list
не может хранить переменные, вызов функции хранит их, и вы можете обращаться к нему только через va_list. Эти переменные действительны только во время вызова, и после этого они получают ovverwriten.
ЭТО НЕ РАБОТАЕТ:
va_list func(int dummy, ...)
{
va_list result;
va_start(result, dummy);
return result;
}
Чтобы выделить память в стеке, без необходимости писать переменную функции используют alloca
. Он работает более или менее как malloc
, но вам не нужно вызывать free
, он автоматически освобождается, когда вы покидаете область действия.
int * local = (int *) alloca(3 * sizeof(int));
local[0] = 10;
local[1] = 20;
local[2] = 30;
Это принципиально то же самое, что писать
int local[3];
local[0] = 10;
local[1] = 20;
local[2] = 30;
Но с alloca
3 не обязательно должна быть константа. Опять же, вы можете использовать его только внутри области приложения, поэтому не возвращайте его из функции.
, если вы хотите из va_list, это несколько типов в одном списке, подумайте о том, как написать такой союз:
union variant
{
int i;
unsigned int u;
float f;
double d;
const char * s;
void * v;
};
То, что вы хотите сделать, это имитировать стек вызовов, чтобы вы могли передать построенный va_list в foo (). Это довольно специфично для компилятора (и предупреждения, существуют различия между даже 32- и 64-разрядными компиляторами). Следующий код предназначен для ТОЛЬКО ДЛЯ РАЗВЛЕЧЕНИЙ! as (если он работает даже в вашей системе), он подвержен поломке. С его помощью я использую плоский буфер памяти и заполняю его счетчиками и цепочкой символов. Вы можете заполнить его соответствующим образом указателями на свои строки и передать их.
Кажется, что это работает в моей системе Windows 7 w / Visual Studio 2008 только для 32-разрядных приложений.
* ПОСЛЕДУЮЩИЙ КОД ИДЕИ !!! *
#define PSEUDOSTACKSIZE ( sizeof(int) + 999 * sizeof(const char*) )
#pragma pack( push,1 )
union PSEUDOSTACK
{
int count;
char data[PSEUDOSTACKSIZE];
};
#pragma pack( pop )
void foo( int count, va_list args )
{
for ( int i = 0; i < count; i++ )
{
char *s = va_arg( args, char* );
printf( "%s\n", s);
}
}
void bar( PSEUDOSTACK data, ... )
{
va_list args;
va_start(args, data.count);
foo( data.count, args);
va_end(args);
}
// And later on, the actual test case code.
PSEUDOSTACK barData;
barData.count = 999;
char *p = barData.data + sizeof(int);
for ( int i = 0; i < 999; i++, p += sizeof(char*) )
{
*reinterpret_cast<char**>(p) = "ThisIsABadIdea";
}
bar( barData );
Теперь я позову свою голову в стыде за то, что подумал о такой идее.
В вашем вопросе отмечен C ++, и есть хорошие способы (например, потоки), чтобы полностью исключить varargs на C ++.
Это отличный пример того, почему va_args может вызвать боль. Если у вас есть шанс изменить подпись foo
, это ваш лучший вариант. Взяв std::vector<std::string>
вместо va_list, вы просто решите свою проблему там.
Если foo
находится во внешней библиотеке, которую вы не можете изменить, моим следующим предложением было бы найти другую библиотеку.
Если ни один из них не является вариантом, кажется, что должен быть способ рекурсивно создать список вызовов с помощью va_list, но я не мог понять, как это сделать.
& lt; just for fun & gt;
#include <stdarg.h>
#include <string>
#include <vector>
#include <iostream>
#define N 6 // test argument count
void foo(int n, ...);
int main(int, char*[])
{
std::vector strings;
std::wstring s(L"a");
int i(0);
// create unique strings...
for (; i != N; ++i)
{
strings.push_back(s);
++s.front();
}
int n_stack_strings(N*sizeof(std::wstring)), // space needed for strings
n_stack(sizeof(int)+n_stack_strings); // overall stack space...needed for cleanup
__asm sub esp, n_stack_strings ; reserve stack space
std::wstring* p_stack(0);
__asm mov p_stack, esp ; get stack pointer
std::wstring* p(p_stack);
std::vector<std::wstring>::iterator string(strings.begin());
// copy to stack
for (; string != strings.end(); ++string, ++p)
new (p) std::wstring(*string);
__asm push N ; argument count...arguments right to left (__cdecl)
__asm call foo
// cleanup
for (p = p_stack; p != p_stack+N; ++p)
p->~basic_string();
__asm add esp, n_stack ; caller has to cleanup the stack (__cdecl)
return 0;
}
void foo(int n, ...)
{
int i(0);
va_list marker;
va_start(marker, n);
for (; i != n; ++i)
std::wcout << va_arg(marker, std::wstring) << std::endl;
va_end(marker);
}
& lt; / just for fun & gt;
va_list
используется typedef для __builtin_va_list
.
– Henri Menke
4 June 2018 в 06:59
... хммм ... может быть, не переносится ... наверняка не приятно ... но может решить проблему yor ...
#include <stdarg.h>
#include <string>
#include <vector>
#include <iostream>
#define N 6 // test argument count
void foo(int n, va_list args);
int main(int, char*[])
{
std::vector<std::wstring> strings;
std::wstring s(L"a");
int i(0);
// create unique strings...
for (; i != N; ++i)
{
strings.push_back(s);
++s.front();
}
foo(N, reinterpret_cast<va_list>(strings.data()));
return 0;
}
void foo(int n, va_list args)
{
int i(0);
for (; i != n; ++i)
std::wcout << va_arg(args, std::wstring) << std::endl;
}
va_list
используется typedef для __builtin_va_list
.
– Henri Menke
4 June 2018 в 06:59