473,386 Members | 1,798 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Calling a function with a literal list of strings?

Hello,

I have a function like this:
/* It actually does something else .... */
void func (int size, const char ** string_list) {
int i;
for (i=0; i < size; i++)
printf("String number %d: %s \n",i,string_list[i]);
}

And would like to (be able) to call it with a literal list of strings,
something like:

func(3 , {"String1" , "Hello", "The last string ..."});

Is that possible? I have tried various casts like (const char **),
(const char [3][]) and (const char [3]*) but to no avail. I am using
gcc with std=gnu99, i.e. I am more than happy to accept C99 features.

Thank you - Joakim Hove

Jul 31 '07 #1
5 2251
In article <11*********************@b79g2000hse.googlegroups. com>
Joakim Hove <jo*********@gmail.comwrote:
>I have a function like this:

/* It actually does something else .... */
void func (int size, const char ** string_list) {
int i;
for (i=0; i < size; i++)
printf("String number %d: %s \n",i,string_list[i]);
}

And would like to (be able) to call it with a literal list of strings,
something like:

func(3 , {"String1" , "Hello", "The last string ..."});

Is that possible? ... I am more than happy to accept C99 features.
If it were more complicated you might be out of luck, but because
C's string literals are kind of funny and sort-of-primitive, you
are in luck:

void f(void) {
func(3, (const char *[]){"1", "2", "3"});
/* you can put in the array size too: (const char *[3]) */
}
>I have tried various casts like (const char **),
(const char [3][]) and (const char [3]*) but to no avail.
The thing in front of the brace list *looks* exactly like a cast,
but is not actually a cast. Instead, it is the type-specifier
part of a "compound literal".

Because the call to func() is within a block (all function calls
in C are always inside a block -- you cannot call a function
outside the outermost block of some other function), the object
created by such a call has automatic duration. In practice, this
means you get runtime code to create the array. You may get
slightly better performance if you just give in and create an
actual object, which you can then make "static":

void f(void) {
static const char *arg[] = {"1", "2", "3"};
func(3, arg);
}

In practice, this eliminates the runtime code: the array is
created at compile-time and exists before main() even gets
called. (In theory, the object could be created exactly once
when f() got called, since you would not be able to tell that
this happened. But only in theory is theory equivalent to
practice. :-) )

Of course, if you do this, you can also automatically count the
number of elements in the array:

#define NELEM(array) (sizeof array / sizeof *(array))
void f(void) {
static const char *arg[] = {"1", "2", "3"};
func(NELEM(arg), arg);
}

and of course all of this now works in C89. The only drawback is
that you must invent a name for each call, and the initialization
tends to move away from the call:

void f(void) {
static const char *argsA[] = {"1", "2", "3"};
static const char *argsB[] = {"Hello", "world"};

func(NELEM(argsA), argsA);
func(NELEM(argsB), argsB);
}

If you resort to C99's "declare anywhere" and variable argument
macros, you can solve both of those with a macro, provided you are
willing to require that each call be on a separate line:

#define PASTE(x, y) x##y
#define XPASTE(x, y) PASTE(x, y)
#define DOIT(...) \
static const char *XPASTE(args, __LINE__)[] = __VA_ARGS__; \
func(NELEM(XPASTE(args, __LINE__)), XPASTE(args, __LINE__))

(Here the PASTE and XPASTE auxiliary macros cause __LINE__ to get
expanded before token-pasting, and __VA_ARGS__ extracts what the
preprocessor sees as multiple arguments, since the comma that
separates the initializers is not protected by parentheses.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 31 '07 #2
Dear Chris,

thank you *very much* for a thorough and informative answer - I have
learned a lot today.
The thing in front of the brace list *looks* exactly like a cast,
but is not actually a cast. Instead, it is the type-specifier
part of a "compound literal".
The type-specifier of a compound literal - neat!
Because the call to func() is within a block (all function calls
in C are always inside a block -- you cannot call a function
outside the outermost block of some other function), the object
created by such a call has automatic duration. In practice, this
means you get runtime code to create the array. You may get
slightly better performance if you just give in and create an
actual object, which you can then make "static":
I won't give in - I just love the compact calls like:

func (3 , (const char *[]) {"S" , "S2" , "..."});

which I can now use - thanks to your help. The call will be issued in
the initialization part of the code, and performance is irrelevant.

Regards

Joakim Hove
Jul 31 '07 #3
"Chris Torek" <no****@torek.netwrote in message
news:f8********@news1.newsguy.com...
If it were more complicated you might be out of luck, but because
C's string literals are kind of funny and sort-of-primitive, you
are in luck:

void f(void) {
func(3, (const char *[]){"1", "2", "3"});
/* you can put in the array size too: (const char *[3]) */
}
gcc version 3.0.4 emits the warning:

ISO C89 forbids compound literals

--
Martin

Aug 1 '07 #4
>"Chris Torek" <no****@torek.netwrote in message
>news:f8********@news1.newsguy.com...
>If it were more complicated you might be out of luck, but because
C's string literals are kind of funny and sort-of-primitive, you
are in luck:

void f(void) {
func(3, (const char *[]){"1", "2", "3"});
/* you can put in the array size too: (const char *[3]) */
}
In article <vd*******************@fe39.usenetserver.com>,
Martin <martin.o_brien@[no-spam]which.netwrote:
>gcc version 3.0.4 emits the warning:

ISO C89 forbids compound literals
Indeed. (The message might be slightly better-phrased if it said
"ISO C90" or "ANSI C89", but the meaning is clear either way.)

However, before the stuff I wrote above, I quoted the following
sentence:
>>>I am more than happy to accept C99 features.
Compound literals are a C99 feature. That GCC warns about them in
its default, neither-C89-nor-C99 not-quite-a-C-compiler compilation
mode (and/or in its C89-specific mode), is probably a good thing.

(I also described how to do the trick without using C99 features, or
with different C99 features. If you use C99 features, you must of
course have support for those in your compiler.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Aug 1 '07 #5
In article <vd*******************@fe39.usenetserver.com>,
Martin <martin.o_brien@[no-spam]which.netwrote:
>>gcc version 3.0.4 emits the warning:

ISO C89 forbids compound literals

Indeed. (The message might be slightly better-phrased if it said
"ISO C90" or "ANSI C89", but the meaning is clear either way.)

However, before the stuff I wrote above, I quoted the following
sentence:
>>>I am more than happy to accept C99 features.
Ah, right. I compile using

gcc -Wall -pedantic -ansi

so the warning is not surprising. And it is a warning: the code does compile
and run. But I wouldn't let that success stop me disallowing such constructs
being used at my workplace in a C89 compiler.

--
Martin

Aug 1 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Joe | last post by:
I have 3 functions: ClientInfoA is doing something ClientInfoB is doing something SelectFunction2Run is a function to determine which function needed to run based on the value of the variable...
19
by: Ross A. Finlayson | last post by:
Hi, I hope you can help me understand the varargs facility. Say I am programming in ISO C including stdarg.h and I declare a function as so: void log_printf(const char* logfilename, const...
7
by: TC | last post by:
Visual Basic used to have a function called String(), which would create a repeating character string. Is that gone in VB .NET? -TC
3
by: Jerome Cohen | last post by:
AI am trying to call a third-party web service. this service expects an XML fragment that contains the request plus other parameter. adding the web reference created the syntax below(reference.vb)....
7
by: Jorgen Haukland, Norway | last post by:
Hi, I have created a Java webservice which runs in IBM WebSphere appserver. I take the WSDL-file and create a VS.NET WinForm application and calls the service running on my PC and everything...
4
by: Henning M | last post by:
Hej All Im relativ new to VB.net and im trying to collect som device information using cfgmgr32.dll I use - Declare Function GetListLength Lib "cfgmgr32.dll" Alias...
3
by: Ivan Zuzak | last post by:
Hello, My Python application calls web services available on the Internet. The web service being called is defined through application user input. The Python built-in library allows access to...
13
by: shalakasan | last post by:
void foo(char str) { char strA = "Hello"; strA = strA; str = str; }
4
by: Tony Lownds | last post by:
(Note: PEPs in the 3xxx number range are intended for Python 3000) PEP: 3107 Title: Function Annotations Version: $Revision: 53169 $ Last-Modified: $Date: 2006-12-27 20:59:16 -0800 (Wed, 27 Dec...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.