Ответ 1
Нет, стандарт C также не поддерживает. Почему вы считаете, что вам нужно преобразовать свой код на С++ в C? Это может показаться довольно сложным - я бы подумал, что писать обертки - это путь, если ваш С++ должен быть вызван с C.
Преобразование С++ lib в ANSI C и похоже, хотя ANSI C не поддерживает значения по умолчанию для функциональных переменных или я ошибаюсь? Я хочу что-то вроде
int funcName(int foo, bar* = NULL);
Кроме того, возможна функция перегрузки в ANSI C?
Вам понадобится
const char* foo_property(foo_t* /* this */, int /* property_number*/);
const char* foo_property(foo_t* /* this */, const char* /* key */, int /* iter */);
Может, конечно, просто называть их по-другому, но используется для С++. Я использовал функцию перегрузки.
Нет, стандарт C также не поддерживает. Почему вы считаете, что вам нужно преобразовать свой код на С++ в C? Это может показаться довольно сложным - я бы подумал, что писать обертки - это путь, если ваш С++ должен быть вызван с C.
Тем не менее, я нашел "трюк", если вы используете GCC.
GCC имеет удобное расширение ## на переменном макросе, которое позволяет вам моделировать аргумент по умолчанию.
Трюк имеет ограничения: он работает только для 1 значения по умолчанию, и аргумент должен быть последним из ваших функциональных параметров.
Вот рабочий пример.
#include <stdio.h>
#define SUM(a,...) sum( a, (5, ##__VA_ARGS__) )
int sum (a, b)
int a;
int b;
{
return a + b;
}
main()
{
printf("%d\n", SUM( 3, 7 ) );
printf("%d\n", SUM( 3 ) );
}
В этом случае я определяю SUM как вызов суммирования со вторым аргументом по умолчанию, равным 5.
Если вы вызываете с двумя аргументами (первый вызов в основном), он будет предварительно записан как: sum (3, (5, 7));
Это означает:
Поскольку gcc является умным, это не влияет на время выполнения, так как первый член последовательности является константой, и он не нужен, он просто будет отброшен во время компиляции.
Если вы вызываете только один аргумент, расширение gcc удаляет VA_ARGS И ведущую кому. Поэтому он предварительно обрабатывается как:
sum (3, (5));
Таким образом, программа дает ожидаемый результат:
10
8
Таким образом, это отлично имитирует (с обычными ограничениями макросов) функцию с двумя аргументами, причем последняя является необязательной с применяемым значением по умолчанию, если не указано.
Существует способ поддерживать столько параметров по умолчанию, которые вам нужны, просто используйте структуру.
// Populate structure with var list and set any default values
struct FooVars {
int int_Var1 = 1; // One is the default value
char char_Command[2] = {"+"};
float float_Var2 = 10.5;
};
struct FooVars MainStruct;
//...
// Switch out any values needed, leave the rest alone
MainStruct.float_Var2 = 22.8;
Myfunc(MainStruct); // Call the function which at this point will add 1 to 22.8.
//...
void Myfunc( struct FooVars *MyFoo ) {
switch(MyFoo.char_Command) {
case '+':
printf("Result is %i %c %f.1 = %f\n" MyFoo.int_Var1, MyFoo.char_Command, MyFoo.float_Var2, (MyFoo.float_Var2 + MyFoo.int_Var1);
break;
case '*':
// Insert multiply here, you get the point...
break;
case '//':
// Insert divide here...
break;
}
}
Насколько я знаю, ANSI C напрямую не поддерживает перегрузку функций или аргументы по умолчанию. Стандартным заменителем перегрузки является добавление суффиксов к имени функции, указывающему типы аргументов. Например, в OpenGL суффикс "3fv" для имени функции означает, что функция принимает вектор из трех поплавков.
Аргументы по умолчанию можно рассматривать как частный случай перегрузки функций.
Попробуйте это.
#include <stdio.h>
#include <stdarg.h>
/* print all non-negative args one at a time;
all args are assumed to be of int type */
void printargs(int arg1, ...)
{
va_list ap;
int i;
va_start(ap, arg1);
for (i = arg1; i >= 0; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}
int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return
0;
}
Ни один из значений по умолчанию или перегрузка функций не существует в ANSI C, поэтому вам придется решать его по-другому.
Вы не можете так легко, так как C не поддерживает их. Более простой способ получить "фальшивую перегрузку" - использовать суффиксы, как уже сказано... значения по умолчанию можно моделировать с помощью функции переменных аргументов, указывая количество переданных аргументов и программно указывая на отсутствие по умолчанию, например:
aType aFunction(int nargs, ...)
{
// "initialization" code and vars
switch(nargs)
{
case 0:
// all to default values... e.g.
aVar1 = 5; // ...
break;
case 1:
aVar1 = va_arg(arglist, int); //...
// initialize aVar2, 3, ... to defaults...
break;
// ...
}
}
Также перегрузка может быть смоделирована с использованием var args с дополнительной информацией, которая должна быть добавлена и передана, а extracode... в основном воспроизводит минималистичную объектно-ориентированную среду выполнения... Другое решение (или, действительно, одно и то же, но с другим подходом) могло бы использовать теги: каждый аргумент представляет собой аргумент типа пары + аргумент (объединение всего набора возможных типов аргументов), там есть специальный тег терминатора (нет необходимости указывать, как многие аргументы, которые вы передаете), и, конечно, вам всегда нужно "сотрудничество" с функцией, которую вы вызываете, то есть она должна содержать дополнительный код для анализа тегов и выбора фактической функции (она ведет себя как своего рода диспетчер)
Вам нужно объявить каждую перегруженную функцию С++ по-разному в C, потому что C не выполняет name mangling. В вашем случае "foo_property1" "foo_property2".
Я думаю, вы можете использовать функцию с переменными аргументами, вот мой пример
#include <stdarg.h>
#include <stdio.h>
void baz( int flag, ... )
{
va_list ap;
char *bar = "baz"; /* default value */
va_start( ap, flag );
if ( flag == 1 )
bar = va_arg( ap, char * );
va_end( ap );
printf( "%s\n", bar );
}
int main( void )
{
baz( 0 );
baz( 1, "foo");
baz( 2 );
baz( 1, "bar");
return 0;
}
вывод
baz
foo
baz
bar
если u ищите, например, man 2 open, они говорят
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
но режим на самом деле является... аргументом