Automatically generate variables

N

Nate

Hello,

I am looking for a method to automatically declare variables in C.
I'm not sure if there is a good way to do this, but I had something
like this in mind...

int i;

for(i = 1; i < 4; i++){

int variable....

}

For example, this loop would declare the following variables all of
type int:

variable1
variable2
variable3

Is something like this possible? Is there another way?

Thanks in advance,

-Nate
 
C

Christopher Benson-Manica

Nate said:
I am looking for a method to automatically declare variables in C.
I'm not sure if there is a good way to do this, but I had something
like this in mind...

No, theres no "good" way. Your way, in particular, is wrong. C
doesn't work like that.
for(i = 1; i < 4; i++){
int variable....
}
Is something like this possible? Is there another way?

Yes; there's a bad (IMHO) way:

#define DECLARE1(type,var) type var##1
#define DECLARE2(type,var) DECLARE1(type,var); \
type var##2
#define DECLARE3(type,var) DECLARE2(type,var); \
type var##3

int main( void ) {
DECLARE3(int,foo);
return 0;
}

You could generate as many #defines as you please using some other
program (say a shell script) and put them in a separate header file.

Alternatively, you could tell us what you *really* want to do and we
can probably suggest a much better alternative.
 
J

Joe Estock

Christopher said:
No, theres no "good" way. Your way, in particular, is wrong. C
doesn't work like that.




Yes; there's a bad (IMHO) way:

#define DECLARE1(type,var) type var##1
#define DECLARE2(type,var) DECLARE1(type,var); \
type var##2
#define DECLARE3(type,var) DECLARE2(type,var); \
type var##3

Or the [slightly] more maintainable way:

#define DECLARE(var, seq) var##seq
int main( void ) {
DECLARE3(int,foo);
return 0;
}

int main(void)
{
int DECLARE(foo, 1);
int DECLARE(foo, 2);

DECLARE(foo, 1) = 10;
foo2 = 5;

printf("foo1: %d foo2: %d\n", DECLARE(foo, 1), foo2);

return(0);
}
 
C

Christopher Benson-Manica

Joe Estock said:
Or the [slightly] more maintainable way:
#define DECLARE(var, seq) var##seq
int main(void)
{
int DECLARE(foo, 1);
int DECLARE(foo, 2);

It's more maintainable, yes, but it also rather defeats the purpose of
the whole exercise, doesn't it? If one wants int foo1 through int
foo100, what's the added benefit of invoking the macro 100 times as
opposed to simply writing the actual declarations?
 
M

Mark McIntyre

Hello,

I am looking for a method to automatically declare variables in C.
I'm not sure if there is a good way to do this,

There isn't - you can't define object names at runtime in C.

You could mallocate an array of objects however, and size it to
whatever size you needed. This is likely to be more useful anyway as
the chances are you will need to loop over the variables.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
J

jacob navia

Nate said:
Hello,

I am looking for a method to automatically declare variables in C.
I'm not sure if there is a good way to do this, but I had something
like this in mind...

int i;

for(i = 1; i < 4; i++){

int variable....

}

For example, this loop would declare the following variables all of
type int:

variable1
variable2
variable3

Is something like this possible? Is there another way?

Thanks in advance,

-Nate

#include <stdio.h>
int main(void)
{
FILE *f = fopen("variables.c","w");
for (int i=0; i<100; i++) {
fprintf(f,"int variable%d\n",i);
}
fclose(f);
}
 
K

Kenny McCormack

#include <stdio.h>
int main(void)
{
FILE *f = fopen("variables.c","w");
for (int i=0; i<100; i++) {
fprintf(f,"int variable%d\n",i);
}
fclose(f);
}

You need to finish what you started. IOW, you forgot to mention:
1) And then compile variables.c as a shared library
2) And then dlopen that library
3) And then enjoy your new symbols

All OT, blah, blah, blah, of course.
 
J

jacob navia

Mark said:
There isn't - you can't define object names at runtime in C.


Wrong

#include <stdio.h>
#include <windows.h>
int main(void)
{
FILE *f = fopen("dynamic.c","w");
void (*fn)(void);
void *ptr;

// 1 Define some structure for instance
fprintf(f,"struct dynamicobject { char *name;int len; };\n");
// 2 Define an object of that type
fprintf(f,"struct dynamicobject var = {\"NoName\",6};\n");
// 3 Define an exported function in a shared object that returns the
// address of the created object
fprintf(f,"void * __declspec(dllexport) \n");
fprintf("GetDynamicObject(void)\n\treturn &var;}\n");
// Done Close the file
fclose(f);
// Compile it. The compiler can change of course :)
system("lcc dynamic.c");
// Link it into a shared object
system("lcclnk -dll dynamic.obj");
// Open the shared object (dlopen under Unix)
void *h = LoadLibrary("variables.dll");
// Get the address of the created function in the shared object
fn = (void (*fn)(int))GetProcAddress("GetDynamicObject");
// Call the function we just compile
ptr = fn();
// And now, ladies and gentlemen
// Here I have a pointer to a dynamically created object
}

Most of my customers buy lcc-win32 as a "Just in time compiler", that
allows them to do this much more efficiently than what is shown here

A JIT compiler is specialized in generating code dynamically. For
instance, if you are modelling molecule interaction you can develop
a special language that is task oriented, compile it to C, then
just JIT compile it into a shared object that you run on the fly.

Of course what you generate is an object, not NAMES...
In this sense the OP is completely wrong of course.
 
J

jacob navia

Kenny said:
You need to finish what you started. IOW, you forgot to mention:
1) And then compile variables.c as a shared library
2) And then dlopen that library
3) And then enjoy your new symbols

All OT, blah, blah, blah, of course.
Yes, see my answer to McIntyre
 
J

Joe Estock

Christopher said:
Joe Estock said:
Or the [slightly] more maintainable way:
#define DECLARE(var, seq) var##seq
int main(void)
{
int DECLARE(foo, 1);
int DECLARE(foo, 2);

It's more maintainable, yes, but it also rather defeats the purpose of
the whole exercise, doesn't it? If one wants int foo1 through int
foo100, what's the added benefit of invoking the macro 100 times as
opposed to simply writing the actual declarations?

Personally I would use an array of type int; I was merely condensing
your example and I missed the very important part of functionality that
was originally sought. After reviewing your original code I see that it
defeats the original intent of declaring several variables at once. I
was distracted by the vast amount of snow outside when I replied to your
original thread.
 
F

Flash Gordon

jacob navia wrote, On 13/02/07 23:25:

No, he is correct.
#include <stdio.h>
#include <windows.h>
int main(void)
{
FILE *f = fopen("dynamic.c","w");
void (*fn)(void);
void *ptr;

// 1 Define some structure for instance
fprintf(f,"struct dynamicobject { char *name;int len; };\n");
// 2 Define an object of that type
fprintf(f,"struct dynamicobject var = {\"NoName\",6};\n");
// 3 Define an exported function in a shared object that returns the
// address of the created object
fprintf(f,"void * __declspec(dllexport) \n");

The above line would prevent the C file that is being written from
compiling on most C compilers.
fprintf("GetDynamicObject(void)\n\treturn &var;}\n");
// Done Close the file
fclose(f);
// Compile it. The compiler can change of course :)
system("lcc dynamic.c");

Here you are using something called a "C compiler". Strangely enough it
is not actually part of C instead it is a tool used to operate on C
sources. On some systems there will not be a C compiler installed and
the user might not have permissions to install one.
// Link it into a shared object
system("lcclnk -dll dynamic.obj");

Here you are using something called a linker which is also not part of C.
// Open the shared object (dlopen under Unix)
void *h = LoadLibrary("variables.dll");

Here you are suggesting using functions that are not part of C that are
not available on all implementations. Oh, and you security systems that
prevent untrusted programs from doing untrusted things like loding
shared objects from untrusted places (i.e. anywhere the user can write to).
// Get the address of the created function in the shared object
fn = (void (*fn)(int))GetProcAddress("GetDynamicObject");

So you are casting something to a function pointer type different from
the definition of the function pointer you are assigning it to. I would
suggest you read the manuals for the compiler you are using to find out
how to enable a sensible level of warnings, but seeing as it is your
compiler I can't imagine why they would not be set already.
// Call the function we just compile
ptr = fn();

Now you are expecting to get a return value from a function that you
have told the compiler does not return anything. Did you compiler not
generate an error here? I know the standard would allow a warning, but
an error would be more appropriate.
// And now, ladies and gentlemen
// Here I have a pointer to a dynamically created object
}

Most of my customers buy lcc-win32 as a "Just in time compiler", that
allows them to do this much more efficiently than what is shown here

Well, I hope you give them something a little closer to being a C
compiler than the above code was to being C.
A JIT compiler is specialized in generating code dynamically. For
instance, if you are modelling molecule interaction you can develop
a special language that is task oriented, compile it to C, then
just JIT compile it into a shared object that you run on the fly.

Now, had you suggested the OP embed some kind of scripting language with
or without a JIT that might have been more sensible. Instead you try to
suggest that using tools at run time that are not installed on most
systems is part of C.
Of course what you generate is an object, not NAMES...
In this sense the OP is completely wrong of course.

The OP is completely wrong to look for a solution to his/her problem or
completely wrong for not being sure if it exists?

There is no mechanism provided in C to do what the OP asked. On *some*
systems you can use things outside of the C language to do the sort of
thing you are suggesting. However you are going so far that you might as
well say that the ability to run Windows Vista is part of C.
 
C

Christopher Benson-Manica

(WRT int foo1 ... int foo100)
Personally I would use an array of type int;

Well, me too, and there probably isn't a great reason for OP not to as
well. There certainly aren't a lot of alternatives, and none that are
good.
I
was distracted by the vast amount of snow outside when I replied to your
original thread.

Posting to comp.lang.c would certainly seem to beat shoveling it :)
 
E

Eric Sosman

jacob navia wrote On 02/13/07 18:05,:
#include <stdio.h>
int main(void)
{
FILE *f = fopen("variables.c","w");
for (int i=0; i<100; i++) {
fprintf(f,"int variable%d\n",i);
}
fclose(f);
}

"variables.c", line 2: undefined or not a type: variable0
"variables.c", line 3: parameter not in identifier list: variable1
"variables.c", line 3: syntax error before or at: int
"variables.c", line 4: parameter not in identifier list: variable2
[...]
"variables.c", line 99: syntax error before or at: int
"variables.c", line 100: parameter not in identifier list: variable98
"variables.c", line 101: parameter not in identifier list: variable99
"variables.c", line 101: syntax error before or at: <EOF>
cc: acomp failed for variables.c

One hundred fifty-one diagnostics all told. An impressive
yield for an investment of a mere nine lines of code.
 
J

jacob navia

Eric Sosman a écrit :
jacob navia wrote On 02/13/07 18:05,:
Nate wrote:




#include <stdio.h>
int main(void)
{
FILE *f = fopen("variables.c","w");
for (int i=0; i<100; i++) {
fprintf(f,"int variable%d\n",i);
}
fclose(f);
}


"variables.c", line 2: undefined or not a type: variable0
"variables.c", line 3: parameter not in identifier list: variable1
"variables.c", line 3: syntax error before or at: int
"variables.c", line 4: parameter not in identifier list: variable2
[...]
"variables.c", line 99: syntax error before or at: int
"variables.c", line 100: parameter not in identifier list: variable98
"variables.c", line 101: parameter not in identifier list: variable99
"variables.c", line 101: syntax error before or at: <EOF>
cc: acomp failed for variables.c

One hundred fifty-one diagnostics all told. An impressive
yield for an investment of a mere nine lines of code.

Add a semi colon at the end of the line.
fprintf(f,"int variable%d;\n",i);
 
O

Old Wolf

For example, this loop would declare the following variables all of
type int:

variable1
variable2
variable3

Is something like this possible? Is there another way?

int variable[4];

Then access them like this:

variable[0] = 4;
variable[1] = 3;
....
variable[3] = 10;

The numbers will be 0 through to one less than the parameter
you specified in the declaration.

If you don't know how many you will need until runtime
then you can write:
int *variable = malloc( 4 * sizeof *variable );

and then access them in the same way as before.
 
N

Nate

For example, this loop would declare the following variables all of
type int:

Is something like this possible? Is there another way?

int variable[4];

Then access them like this:

variable[0] = 4;
variable[1] = 3;
...
variable[3] = 10;

The numbers will be 0 through to one less than the parameter
you specified in the declaration.

If you don't know how many you will need until runtime
then you can write:
int *variable = malloc( 4 * sizeof *variable );

and then access them in the same way as before.

OW,

This solution will work perfectly for what I'm trying to do, thank you
for your suggestion.

In fact, I will know the size needed for the array each time so it
will make the solution that much easier to implement.

Thanks again,

-Nate
 
S

santosh

Nate said:
For example, this loop would declare the following variables all of
type int:

Is something like this possible? Is there another way?

int variable[4];

Then access them like this:

variable[0] = 4;
variable[1] = 3;
...
variable[3] = 10;
OW,

This solution will work perfectly for what I'm trying to do, thank you
for your suggestion.
<snip>

You could've said you wanted arrays. Your C text should have atleast a
chapter on it.
 
M

Mark McIntyre


Right.
#include <stdio.h>
#include <windows.h>

Beep beep. This isn't C.
void *h = LoadLibrary("variables.dll");
fn = (void (*fn)(int))GetProcAddress("GetDynamicObject");

This isn't either.

But then you knew this, you just wanted to disagree with me I suspect.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
Y

Yevgen Muntyan

Mark said:
Right.
Agreed.


Beep beep. This isn't C.


This isn't either.

Nonsense. It is C. It's not strictly conforming, it won't work
almost anywhere, it's rather useless, it's off-topic here, all this
was in details explained in another reply to JN post. But it is C,
where "C" means "C language as defined by the ISO standard".

Yevgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top