0

I have the following c code:

struct {
    short s;
    int n;
} variableName;

I want to write a function to capture this variable like so

void func(MyStruct* var){
    //do stuff
}

func(&variableName);

I would like to do this without providing a definition for the struct. Is there a way to capture variableName?

3 Answers3

2

No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually:

void func(short s, int n) { ... }

Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be).

You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. Pure C does not have a facility for this; the compiler wants to know the layout of a structure in advance.

(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.)

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
  • Essentially, I have a anonymous union with anonymous structures declared within it and I was hoping to be able to write a function for each anonymous structure within the union. If I have to provide definitions it'll just be an inconvenience to a script I wrote generating c code. Thanks for the response! – JComputerScience Jan 17 '19 at 22:43
  • 1
    @JComputerScience: Gotcha. I think you'll probably just want to generate declarations. I believe the very latest C standard provides for anonymous structs inside a union, but I think you'll have to declare *something* in order to actually pass that union into a function. Further unnatural acts may be possible if the generated code isn't meant to be especially human-readable, this page might have some pointers for you https://stackoverflow.com/questions/8932707/what-are-anonymous-structs-and-unions-useful-for-in-c11 – Ben Zotto Jan 17 '19 at 23:44
2

Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" in the OP, unless it was edited after. The question makes less sense now, but heres how you could normally pass a struct to a function for future readers.

#include <stdio.h>

    struct StructName{
        short s;
        int n;
    };

    void func(struct StructName struct_var){
            printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
        }

    int main(){
        struct StructName struct_var;
        struct_var.s = 0xDEAD;
        struct_var.n = 0xBEEF;
        func(struct_var);
    }

//It looks like you are trying to use the definition as a variable. Here the definition is StructName and the variable is struct_var.

this sample code outputs: Param values are: DEAD BEEF

Bwebb
  • 675
  • 4
  • 14
  • https://stackoverflow.com/questions/1972003/how-to-compile-c-code-with-anonymous-structs-unions Maybe this question will help with what your trying to do. – Bwebb Jan 17 '19 at 22:51
0

If you use clang or gcc, you may be able to use typeof:

struct foo {
    struct {
        int i;
    } anon;
} foo;

void do_something(typeof(foo.anon)* member) {
    member->i = 1;
}

If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon).

This comes with a lot of downsides. The most obvious ones are that:

  • it's not standard, and it ties you to clang/gcc
  • it's pretty darn ugly
  • it might not behave as you expect anyway

For instance, structurally-equivalent anonymous types do not have the same type, so in something like this:

struct foo {
    struct {
        int i;
    } anon1;
    struct {
        int i;
    } anon2;
} foo;

anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both.

In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous.

Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load:

struct {
    struct not_anon {
        int i;
    } anon;
} foo;

void do_something(struct not_anon* member) {
    member->i = 1;
}
zneak
  • 134,922
  • 42
  • 253
  • 328