Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 309909
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T07:47:06+00:00 2026-05-12T07:47:06+00:00

I recently discovered that something compiles(not sure that it’s legal though). My need for

  • 0

I recently discovered that something compiles(not sure that it’s legal though). My need for such a thing comes from this: My project outputs machine code for a selected arch.(which may or may not be the same arch. as the one running the program). So, I would like to support up to 64bit architectures right now(while also supporting existing 32 and 16 bit archs.) My current solution is for new_state’s ‘base’ to just be a uint64_t, and manually casting to 16 and 32 bits as needed. Though, I discovered you can compile unions in a function parameter. So a function as this compiles:

int pcg_new_state(pcg_state *s,int arch,void *mem,int sz,
             union{
    uint16_t b16;
    uint32_t b32;
    uint64_t b64;
}base ,int self_running);

Is this kind of thing at all “legal” though or supported by any other compilers? And also, I can’t figure out how to call this function without also creating a union and then passing this union to new_state.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T07:47:06+00:00Added an answer on May 12, 2026 at 7:47 am

    To summarize: Yes, that is valid in C, although being illegal in C++. The latter contains this note which explains the difference

    Change: In C++, types may not be defined in return or parameter types. In C, these type definitions are allowed

    Example:

    void f( struct S { int a; } arg ) {} // valid C, invalid C++
    enum E { A, B, C } f() {} // valid C, invalid C++
    
    • Rationale: When comparing types in different compilation units, C++ relies on name equivalence when C relies on structural equivalence. Regarding parameter types: since the type defined in an parameter list would be in the scope of the function, the only legal calls in C++ would be from within the function itself.
    • Effect on original feature: Deletion of semantically well-defined feature.
    • Difficulty of converting: Semantic transformation. The type definitions must be moved to file scope, or in header files.
    • How widely used: Seldom. This style of type definitions is seen as poor coding style.

    The structural equivalence in C is done by the concept of “type compatibility”. This allows C to treat many types as if they were identical, even though they are theoretically distinct – because they are declared in two different translation units. In C++, this concept doesn’t exist, because types have linkage and are matched to the same entity (i.e to allow member functions to link against each other).

    Note that the above cited explanation is based off C89, which did not consider the tag name of a struct in determining type compatibility. In a C89 draft, the relevant text reads as the following:

    Moreover, two structure, union, or enumeration types declared in separate translation units are compatible if they have the same number of members, the same member names, and compatible member types; for two structures, the members shall be in the same order;

    In C99, type checking is more stricter: If one struct has a tag name, the other struct declaration has to have that same tag name. So in your unnamed union type case, to declare a function in another TU that has a compatible type, you would need an unnamed union again if you want to have valid C99 code (without undefined behavior) – you cannot “trick” around, and use a named union in one TU, and an unnamed union in another TU. It looks to me that this “trick” is valid for C89, though. C99 TC3 6.2.7/1:

    Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are complete types, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types, and such that if one member of a corresponding pair is declared with a name, the other member is declared with the same name. For two structures, corresponding members shall be declared in the same order.


    The way you want to do it doesn’t work. Calling a function will convert the arguments to the type of the parameters as if by normal assignment.

    So for this to work, you will have to have an argument that’s compatible with the parameter type. For two unions declared in the same translation unit, this means that their type must equal – that’s the only way you can come up with a compatible type within the same translation unit. But this cannot work, because the declaration of the unnamed union creates an unique new type – no way to “refer back” to it using another declaration.

    So, to summarize – you have to give the union type a name. To avoid creating a separate variable to pass the needed base argument, I would declare it outside the function, and create functions that give back an union you may pass over

    union base_type {
            uint16_t b16;
            uint32_t b32;
            uint64_t b64;
    };
    
    int pcg_new_state(pcg_state *s,int arch,void *mem,int sz,
                      union base_type base,int self_running);
    
    union base_type base_b16(uint16_t t) 
    { union base_type b; b.b16 = t; return b; }
    union base_type base_b32(uint32_t t) 
    { union base_type b; b.b32 = t; return b; }
    union base_type base_b64(uint64_t t) 
    { union base_type b; b.b64 = t; return b; }
    

    Now, it can look like the following

    pcg_new_state(...., base_b32(4211), ....);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

As almost everybody knows strings in Java are immutable. Recently I discovered something that
I've discovered something pretty amazing that works recently. I am wanting to know if
So I recently discovered that you can force Entity Framework not to translate your
I recently discovered something (that surprises me) when opening an audio file in firefox
I recently discovered that the commercial printing company that my office uses does not
I recently discovered that all Windows 7 machines have an handwriting recognition API within
I recently discovered that when you have a page set to session readonly and
I recently discovered that I can use lambdas to create simple event handlers. I
I recently discovered that a sql query that was running fine earlier is now
I recently discovered that in C++ you can overload the function call operator, in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.