Skip to main content
GameDev.net gamedev.net
✓ Solved 🔒 Locked

How to use a well defined array as function parameter in C?

Started by TooOld2rock-nRoll May 8 at 6:22 PM 13 replies 1.2k views
Original Post
TooOld2rock-nRoll
TooOld2rock-nRoll

It's raining outside, it's going to be a long cold weekend and the dog is tired of pretending to understand what I'm saying....

Can't complain of the sound track though, Cool Breeze by The Jeremy Spencer Band is current playing.

So I thought of picking your brains a title if you don't mind.

In C++ I can do this kind of shenanigans:

void TheClass::reallyCoolMethod (const unsigned (¬_very_important)[4] = { }) { }

The compiler will understand that the method expects an array of size 4 and if none is provided, it will use a static zero initialized array.

In C though, I can do something similar that is significant to the user, but not guarantied by the compiler since the size 4 array will just be a variable pointer array for the function abuse as it wishes. That is not really a problem, I'm not allergic to regular pointers, have an understanding of how arrays work in memory and how to keep things tight.

What is driving me crazy is HOW to pass a {0,0,0,0} to the damn function?!?!

Most of the time the parameter in not important, there will not be an formal array with meaningful values, I just want to do:

//assume very crussial code here!
muchMoreInterestingCFunction ({0,0,0,0});

So, what is the proper syntax for in place casting a static array as function parameter in pure C?

Also, how are you guys searching for just C results in google and such? Because it apparently can´t care less for the distinction of C and Cpp on the results.....

"No, you're never too old to rock and roll
If you're too young to die"
Accepted Answer

Search engines are 100% unusable now. And even the AI search summary thing is useless. Basically either you already know it or you're not going to find it. That's just how it is.

In C, you can do stuff like (auto being C23):

auto x = (int[]) { 4, 3, 5 };

I wish C had the ability to do: (auto) { values... } and automatically deduce what it should replace auto with. That would already help a lot.

But in general, in C, you just pass a pointer and a length, if the length is dynamic.

So you just call:

void test(int x[4]);

test((int[]){1,2,3,4});
test((int[4]){});
Walk with God.
Aressera
Aressera

Why not just:

const unsigned array[4] = {0,0,0,0};
muchMoreInterestingCFunction (array);

If the parameter is optional, then just pass NULL (and check for that inside the function).

TooOld2rock-nRoll
TooOld2rock-nRoll

@Aressera yes, both options are the usual way of doing it.

C++ just makes this special case very ascetically pleasing, it would be nice to keep something like it.

Also in my particular application, even when the parameter is useful, it will be much easier and clearer to declare the array in the function call.

In practice, it is a padding for images.

"No, you're never too old to rock and roll
If you're too young to die"
Aressera
Aressera

One option is to wrap the array values in a struct, then you can do this (I think):

typedef struct {
  unsigned left, right, down, up;
} Padding;

muchMoreInterestingCFunction( (Padding){ 0, 0, 0, 0 } );

You could wrap it in a macro to make it nicer to use.

Alberth
Alberth

TooOld2rock-nRoll wrote:

how are you guys searching for just C results in google and such?

Some search engines accept '-abc' as a way to express ignoring/dropping answers with abc in it. Similarly, '+xyz' may also exist to express you want xyz in the answers.

Since the introduction of AI however, search engines have become much less useful, as they seem to completely ignore niche areas in the initial results. If you however then open the AI bot dialogue and start asking specific questions, you can get the results you want at least in some cases.

For C / CPP detail questions, I tend to go to the cppreference site directly, as that is the definitive guide. It takes some experience to read/understand it though.

JoeJ
JoeJ

I can do:

static int defaultX[4] = {};
void test (int x[4] = defaultX)
{
	SystemTools::Log("%i %i %i %i\n", x[0],x[1],x[2],x[3]);
}


int main (int, char**)
{

	SystemTools::SetLogFile ("c:\\dev\\Render_log.txt");

	test();
	int x[4] = {1,2,3,4};
	test(x);

And it prints as expected:

0 0 0 0
1 2 3 4

I'm using C++ compiler, but i guess it works with C too.

frob
frob

TooOld2rock-nRoll wrote:

In C++ I can do this kind of shenanigans:

You misinterpret what the compiler is doing.

You are telling other humans that it expects an array of a specific size, but there is no functional difference between your 4-value array version and a raw pointer version. You specify an integer array of a size, but to the compiler it boils down to just unsigned * . The compiler also deals with the const, but that's about the insides, not the interface, the thing that can be linked against doesn't care. It's just a pointer.


The version you described about creating four-value default argument is something that was added to C++, added to the very early pre-standard versions of C++. Default arguments are just automatically created wrappers around functions that create multiple prototypes.

In your case, the actual function: void TheFunction(const unsigned *) {} and the default argument wrapper version: void TheFunction() { const unsigned arg[4]={}; TheFunction(arg); } The compiler is smart enough to optimize wrapper away, behind your back it stores the block of 4 values on the stack and passes the address, then discards it when the function is complete.

In some of the earliest pre-C++-standards compilers in the 1980s you could find little stub functions in the map files that served as the wrappers for the default argument versions.

TooOld2rock-nRoll wrote:

In C though, I can do something similar that is significant to the user, but not guarantied by the compiler since the size 4 array will just be a variable pointer array for the function abuse as it wishes

Nope, C++ doesn't guarantee it either. No version of the language standard ever has.

In both C and C++ the actual function signature, the thing that gets linked against, is a pointer to the first element. If compiled C++ code doesn't have an argument when it is used the compiler looks at the signature, quickly makes an invisible wrapper as above, and substitutes that locally.

TooOld2rock-nRoll wrote:

What is driving me crazy is HOW to pass a {0,0,0,0} to the damn function?!?!

unsigned array[4] = {0}; // Introduced in C99.  Starting with C23 you can also use = {}, though many compilers allowed it long before.
TheFunction(array);

TooOld2rock-nRoll wrote:

Also, how are you guys searching for just C results in google and such?

I've got copies of the old standards, bought years ago. I have a collection of them that I keep around with all the versions. Same with ECMAScript (JavaScript) starting with the 3rd Edition (1999), and C# back to December 2002. Similarly I've got old versions of Intel architecture and assembly references dating back to 2001, though all of these are possible to look up. It's just easier to keep them around in a single "programming standards" directory.

C89 and C99, and C++98, they cost me $18 which was painful but nice to have back in college. The C++03 update was $21.

After that, the final drafts before standardization were published online for free. They're not hard to look up if you search for them. The title pages are a little different, instead of being labeled "International Standard..." they're labeled "Working Draft, Standard for ...",

but otherwise the final draft matches the published standard.

RmbRT
RmbRT

JoeJ said:
I'm using C++ compiler, but i guess it works with C too.

No. C still does not have default parameter values, as far as I am aware. But as I understand it, the question was about how to syntactically create that value in-line, without having to declare it into a variable first. Which thankfully is just doing (type[]){values...} for dynamically sized arrays, or (type[N]){} for the 0-initialised, explicitly sized array.

Walk with God.
TooOld2rock-nRoll
TooOld2rock-nRoll

Hummmm I love the smell of chaos in a saturday night :D

So glad I started this conversation, feels like old times again, let me answer what I can before cooking dinner.

Aressera wrote:

typedef struct {
unsigned left, right, down, up;
} Padding;

That is a elegant solution to the problem, I will use it if everything else fails!

RmbRT wrote:

test((int[]){1,2,3,4});

That is exactly what I was looking for, the proper syntax for static casting a fixed array, what do you call that??? Because I tried every combination I could thing of and found nothing but beginners guides to pointers.

I will test it monday I accept the answer.

JoeJ wrote:

I'm using C++ compiler, but i guess it works with C too.

No it doesn't, C is a little behind on that area, but I honestly found it creates A LOT of problems for maintenance and that is a good reason for C not to adopt it as is.

frob wrote:

You misinterpret what the compiler is doing.

No I didn't, I was misguided by other people to believe the latest C++ could do that in that way.

Your explanation tough is [insert chefs kiss meme here], anyone in the future should find this useful.


Thanks all, I think I already got what I needed o/


Ps: search engines now seam to just ignore the words you type and just look for what they think you are actually trying to find.

What REALLY frightens me (no exaggeration) is that same if not most of the first page links seam to be AI slop generated FOR my search, it answers nothing, it helps on nothing, but it made me click on several before realizing my mistake.

"No, you're never too old to rock and roll
If you're too young to die"
frob
frob

That is exactly what I was looking for, the proper syntax for static casting a fixed array, what do you call that???

Initializer list. Been in C since C99, C++ with C++11.

You can also use designated initializers, in C for years and somewhat recently adopted in C++, C++20 I believe.

TooOld2rock-nRoll
TooOld2rock-nRoll

frob wrote:

You can also use designated initializers, in C for years and somewhat recently adopted in C++, C++20 I believe.

I was not aware of designated initializers until very recently, it is useful that it defaults the entries not explicitly declared to zero, but if you are using C, I like the classy memset to 0x00.

The past many years, I was more focused in embarked development, cellphones before Android, micro controllers and such, there was not much motivation or opportunity to keep exploring new language features.

"No, you're never too old to rock and roll
If you're too young to die"
frob
frob

if you are using C, I like the classy memset to 0x00.

It's been in the C standard since C99, many compilers supported it years earlier.

Memset works, but in some cases is unnecessary. Zero-initialized leverages the compiler's knowledge, either setting it or relying on the pre-existing set values.

RmbRT
RmbRT

TooOld2rock-nRoll said:
Ps: search engines now seam to just ignore the words you type and just look for what they think you are actually trying to find.

What REALLY frightens me (no exaggeration) is that same if not most of the first page links seam to be AI slop generated FOR my search, it answers nothing, it helps on nothing, but it made me click on several before realizing my mistake.

First we got AI generated sites that broke search. Then, search engines switched to AI in their search metrics instead of having deterministic mathematical metrics. And then they basically abandoned trying to find anything altogether, and now just spew out some nonsense AI-generated search summary.

Old search engines let you accurately find exactly what you typed in, but I don't think they exist anymore. At least I don't know of any. And now that generative AI exists, it's basically impossible to return to the old days of a searchable internet, because these idiots are going to continue flooding everything with AI-generated stuff. And because ads exist, it is profitable for them to do so. And you also don't want an internet where everything is linked to a government-issued proof of personhood. They irreversibly poisoned it. And i also think that search engines now no longer really remember far back either.

Walk with God.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.