Syntax for union parameter

R

Rick C. Hodgin

I have had occasion where I've needed to do something like this:

struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};

void main(void)
{
struct SBGRA color = { 255,255,255,255 }; // white, full alpha
foo(color); // do something with that color
}

void foo(SBGRA color)
{
union {
struct SBGRA color;
unsigned int _color;
} u;

// Convert SBGRA to an unsigned int
u.color = color;
some_other_function(u._color); // Do something with that number
}

-----
Is there a way to do something like this in C (to declare a union in
the function definition line)?

void foo(union { SBGRA color, unsigned int _color } u)
{
some_other_function(u._color);
}

There are only certain occasions where I need it, and rather than declare
something global, it would be nice to be able to declare the local union
in the definition to allow existing data passed in the structure format
to continue unchanged, but then to access it without the extra local
union definition, and in non-structure form.

Best regards,
Rick C. Hodgin
 
K

Keith Thompson

Rick C. Hodgin said:
I have had occasion where I've needed to do something like this:

struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};

void main(void)

This should be int main(void)
{
struct SBGRA color = { 255,255,255,255 }; // white, full alpha
foo(color); // do something with that color
}

void foo(SBGRA color)
{
union {
struct SBGRA color;
unsigned int _color;
} u;

// Convert SBGRA to an unsigned int
u.color = color;
some_other_function(u._color); // Do something with that number
}

-----
Is there a way to do something like this in C (to declare a union in
the function definition line)?

void foo(union { SBGRA color, unsigned int _color } u)
{
some_other_function(u._color);
}

There are only certain occasions where I need it, and rather than declare
something global, it would be nice to be able to declare the local union
in the definition to allow existing data passed in the structure format
to continue unchanged, but then to access it without the extra local
union definition, and in non-structure form.

You're creating an anonymous type that's visible only inside the
function. How are you going to pass a value of type

union { SBGRA color, unsigned int _color }

to foo? You can create another identical type, but it's still going to
be distinct from the one defined in the parameter list.

Just define the union type so it's visible to the function and to any
callers.
 
R

Rick C. Hodgin

You're creating an anonymous type that's visible only inside the
function. How are you going to pass a value of type
union { SBGRA color, unsigned int _color }
to foo?

Ideally? :) As either SBGRA or unsigned int. The compiler would/
should recognize either as being valid and fulfilling the calling
parameter requirements.
You can create another identical type, but it's still going to
be distinct from the one defined in the parameter list.

I thought that might be in.
Just define the union type so it's visible to the function and
to any callers.

Best regards,
Rick C. Hodgin
 
K

Kaz Kylheku

I have had occasion where I've needed to do something like this:

struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};

void main(void)
{
struct SBGRA color = { 255,255,255,255 }; // white, full alpha
foo(color); // do something with that color
}

void foo(SBGRA color)
{
union {
struct SBGRA color;
unsigned int _color;
} u;

// Convert SBGRA to an unsigned int
u.color = color;
some_other_function(u._color); // Do something with that number
}

This trick is quite nonportable. Even if the elements of the structure
are packed (which they might not be) and so that they are laid out like an
unsigned int (which might not be four bytes), there is still the question of
byte order. Is "blu" at the low-end of the unsigned int, or high end?

A more portable approach is to do some shifting and masking arithmetic
to create a 32 bit value out ouf the four 8 bit values:

unsigned long SRGBA_to_scalar_color(SRGBA srgba)
{
return ((unsigned long) srgba.alp) << 24 |
((unsigned long) srgba.red) << 16 |
((unsigned) srgba.grn ) << 8 |
(unsigned) srgba.blu;
}

From this basis we can optimize.

#if CONFIG_SUCH_AND_SUCH_PLATFORM && CONFIG_SUCH_AND_SUCH_ASSUMPTION
unsigned long SRGBA_to_scalar_color(SRGBA srgba)
{
/* some faster code not based on shifting and masking*/
}
#elif CONFIG_SOMETHING_ELSE
unsigned long SRGBA_to_scalar_color(SRGBA srgba)
{
/* some different faster code not based on shifting and masking*/
}
#else
/* stick the above portable function here */
#endif
Is there a way to do something like this in C (to declare a union in
the function definition line)?

void foo(union { SBGRA color, unsigned int _color } u)
{
some_other_function(u._color);
}

The parameter then has a type which is only known in the scope of the
parameter declaration. This means that there is no way to write a call
to this function that doesn't require a diagnostic (and likely stops
compilation).

However, though not achieving quite the above slickness, you can
do something like this: type punning between a union and struct:

void foo(SGBRA color c)
{
typedef union { SBGRA color; unsigned int color_word; } USGBRA;
USGBRA *pu = (USGBRA *) c;
some_other_function(pu->color_word);
}

This may not be in a well-defined area of behavior, since we have not
actually stored a value into one member of a union and retrieved
another, but simply overlaid a union alias on a struct.

If you do this kind of type punning on GCC then compile (at least that source
file) with -fno-strict-aliasing.
 
B

Ben Bacarisse

Rick C. Hodgin said:
Ideally? :) As either SBGRA or unsigned int. The compiler would/
should recognize either as being valid and fulfilling the calling
parameter requirements.

I suspect one reason this is not done is that it is not in general
possible to tell just form the argument expression which union member is
to be initialised. However, see below...
I thought that might be in.

And then your old friend compound literals come in handy again, this
time with anther C99 feature: designated initialisers. If you have

union colour { struct scolour colour_s; unsigned int colour_i; }

void some_function(union colour c) {...}

You can pass union objects without the need to name them:

struct scolour cs = {...};

some_function((union colour){ .colour_s = cs });
some_function((union colour){ .colour_i = 42 });
some_function((union colour){ .colour_s = {9, 8, 7, 6} });

You can, of course, also use this technique to convert from one form to
the other:

printf("%x\n", (union colour){ .colour_s = {1, 2, 3, 4} }.colour_i);
 
K

Keith Thompson

Rick C. Hodgin said:
Ideally? :) As either SBGRA or unsigned int. The compiler would/
should recognize either as being valid and fulfilling the calling
parameter requirements.

No. SBGRA, unsigned int, and your anonymous union are three distinct
types, and there are no implicit conversions between the union type and
the types of its members.

[...]
 
B

BartC

Rick C. Hodgin said:
I have had occasion where I've needed to do something like this:

struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};
struct SBGRA color = { 255,255,255,255 }; // white, full alpha
union {
struct SBGRA color;
unsigned int _color;
} u;
I love compound literals. :)

I have a thing for anonymous structs and unions. So I would probably deal
with this by building the _color field into the original struct:

#define byte unsigned char

struct SBGRA
{
union
{
struct
{
byte blu;
byte grn;
byte red;
byte alp;
};
unsigned colour;
};
};

struct SBGRA c={127,191,255,255};

printf("%d %d %d %d\n",c.blu,c.grn,c.red,c.alp);
printf("%X\n",c.colour);

However I don't know how widely this feature is supported.

(BTW SBGRA isn't the easiest name to get right. It took ten minutes puzzling
over compilers errors, when I mistyped the second one as SBRGA. Of course
the compiler couldn't just tell me that SBRGA was undefined, just 'storage
size not known', 'too many initialisers' etc.)
 
R

Rick C. Hodgin

No. SBGRA, unsigned int, and your anonymous union are three distinct
types, and there are no implicit conversions between the union type and
the types of its members.

I realize that's how it works today. It's my wish list thinking there.
I will implement this union parameter feature in RDC.

Best regards,
Rick C. Hodgin
 
R

Rick C. Hodgin

I have a thing for anonymous structs and unions. So I would probably deal
with this by building the _color field into the original struct:

#define byte unsigned char
struct SBGRA
{
union
{
struct
{
byte blu;
byte grn;
byte red;
byte alp;
};
unsigned colour;
};
};

Using the relaxed syntax allowances of Visual C++, I have something
similar (line 810):

https://github.com/RickCHodgin/libsf/blob/master/vvm/core/common/common.h

struct SBGRA c={127,191,255,255};

printf("%d %d %d %d\n",c.blu,c.grn,c.red,c.alp);
printf("%X\n",c.colour);

However I don't know how widely this feature is supported.

(BTW SBGRA isn't the easiest name to get right. It took ten minutes puzzling
over compilers errors, when I mistyped the second one as SBRGA. Of course
the compiler couldn't just tell me that SBRGA was undefined, just 'storage
size not known', 'too many initialisers' etc.)

May I introduce you to the Visual Studio IDE? If you use the Whole Tomato
plugin called "Visual Assist X" it will handle auto-suggestions for you.
Simply type "SB" and press tab and it fills it in. In addition, the code
preview window is auto-populated with the source line of the definition so
you can immediately see its members at a glance.

You can see me coding here (1920 x 1200 scaled down for the video):
http://www.visual-freepro.org/videos/

And specifically here you can see how the Visual Studio IDE works (the
music is the 2006 Celtic Woman performance at Slane Castle I think):
http://www.visual-freepro.org/videos/2013_02_14__01_rxml_development.ogv

Best regards,
Rick C. Hodgin
 
B

Ben Bacarisse

Rick C. Hodgin said:
Using the relaxed syntax allowances of Visual C++, I have something
similar

For the record, it's official C11 syntax, so it can be accepted by
uptight compilers too.

<snip>
 
J

James Kuyper

I have had occasion where I've needed to do something like this:

struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};

The standard allows an implementation to insert arbitrary padding
between members of a struct. This is extremely unlikely when the members
are all of character type, because there's no possibility of alignment
issues that would require padding. However, since your code absolutely
depends upon the absence of such padding, you really should be using a C
construct which actually forbids padding, such as unsigned char[4],
rather than a struct.
void main(void)

The return type of main must be int. Many text books get this wrong, and
many people write their code accordingly, and as a result many compilers
accept such code - those books and those people are all ignoring what
the C standard says. Those compilers can actually be fully conforming -
the behavior of such a program is undefined, which means it's perfectly
acceptable for the implementation to translate it the way you've
incorrectly assumed it must be translated.. However, a decent compiler
should warn you about this mistake.
{
struct SBGRA color = { 255,255,255,255 }; // white, full alpha
foo(color); // do something with that color
}

void foo(SBGRA color)
{
union {
struct SBGRA color;
unsigned int _color;
} u;

There are many contexts where you're prohibited from defining an
identifier that starts with '_'. This is NOT one of those contexts.
However, can you tell me precisely when it is safe to define such an
identifier? If not, I recommend avoiding them entirely, at least until
you've had time to memorize the relevant rules (section 7.1.3 of the C
standard).

From past experience with you, I doubt that you're concerned about
portability - but the C standard provides no guarantees that unsigned
int is long enough to alias struct SBGRA, even if it had no padding.
unsigned char is allowed to have more than 8 bits, and there are real,
modern machines where it has 16 bits. unsigned int is allowed to have as
few as 16 bits, and there are real, modern machines where it is. You
should use uint8_t and uint32_t, respectively, from <stdint.h>. Those
are optional types, but it's rather unlikely that either of them is
unsupported. On any platform where either one is not supported, nothing
remotely similar to what you've written will work, so it's a good idea
to write your code in such a way that it would fail at compile time with
a diagnostic on such a platform.

There's also another and much more plausible portability issue, which
you might be equally unconcerned about. Even assuming you are using
uint8_t[4] and uint32_t, there's still no guarantees about which bits in
u._color correspond to each element of u.color. In particular, there's
the big-endian/little-endian issue. If you need to port this code
between big-endian and little-endian machines, you'll need to decide
whether the byte order imposed by u.color or the bit order of u._color
is more important. I would expect the byte order of u.color is the
relevant one, and I'll use that assumption below.
// Convert SBGRA to an unsigned int
u.color = color;
some_other_function(u._color); // Do something with that number
}

-----
Is there a way to do something like this in C (to declare a union in
the function definition line)?

void foo(union { SBGRA color, unsigned int _color } u)
{
some_other_function(u._color);
}

In order to call foo() with defined behavior, you must pass it an object
of a type compatible with the unnamed type of u. Since that type is
unnamed, that is, in fact, extremely difficult (but possible) to
arrange. I wrote up a long explanation of why it was difficult, and how
it could be arranged, with the net conclusion that it makes much more
sense to give up your insistence that the union be anonymous. It is far
easier to make foo() usable if you give the union either a tag name or a
typedef.

However, after putting a lot of effort into that explanation, I realized
that it's probably irrelevant, because I'm almost certain that you don't
want to create an object of compatible type to pass to foo(). I suspect
that you want to pass either a struct SBGRA or an unsigned int to foo(),
possibly both, and neither of those types is compatible with the type of
u. You can't make anything like that work portably in C.

There's probably many implementations where you could get it to work if
you use a K&R style declaration for foo() rather than a function
prototype, in any translation unit where foo() is called. Note that the
definition of foo() given above includes a function prototype:
therefore, if you wish to call foo() from later on within the same
translation unit where it is defined, you should change the definition
accordingly. I would not recommend that approach, but if you're
completely unconcerned with portability, go ahead and give it a try, it
might work (or it might not).

The right way to do this is to pass around uint32_t values, and then
using constructs such as ((uint8_t*)color)[2] to access the red byte of
the object that it's stored in.
 
R

Rick C. Hodgin

I have had occasion where I've needed to do something like this:
struct SBGRA
{
unsigned char blu;
unsigned char grn;
unsigned char red;
unsigned char alp;
};

The standard allows an implementation to insert arbitrary padding
between members of a struct. This is extremely unlikely when the members
are all of character type, because there's no possibility of alignment
issues that would require padding. However, since your code absolutely
depends upon the absence of such padding, you really should be using a C
construct which actually forbids padding, such as unsigned char[4],
rather than a struct.

I always use whatever compiler setting is required to align everything to
bytes. If I need a particular struct aligned for some reason I use a
struct-instance override (such as #pragma align 16).
The return type of main must be int. Many text books get this wrong, and
many people write their code accordingly, and as a result many compilers
accept such code - those books and those people are all ignoring what
the C standard says. Those compilers can actually be fully conforming -
the behavior of such a program is undefined, which means it's perfectly
acceptable for the implementation to translate it the way you've
incorrectly assumed it must be translated.. However, a decent compiler
should warn you about this mistake.

I used it only to illustrate. I noticed in one of the coding examples
posted to me a void main(void) declaration. I had been using the ones
I am familiar with int main(int argc, char* argv[]) and it's a lot of
typing. So, for illustration I did the shorter version. :)
There are many contexts where you're prohibited from defining an
identifier that starts with '_'. This is NOT one of those contexts.
However, can you tell me precisely when it is safe to define such an
identifier? If not, I recommend avoiding them entirely, at least until
you've had time to memorize the relevant rules (section 7.1.3 of the C
standard).

I use them in all cases like this, and for global constants. All constants
in my systems are prefixed with an underscore, and are all caps. It's a
convention I picked up from my assembly days and have just kept.
From past experience with you, I doubt that you're concerned about
portability - but the C standard provides no guarantees that unsigned
int is long enough to alias struct SBGRA, even if it had no padding.
unsigned char is allowed to have more than 8 bits, and there are real,

I don't actually use int in my code. I have done that here so people can
paste the code into their editors and test it. I have indicated previously
that I use explicit types:

s8, u8 -- signed, unsigned 8-bit quantity
s16, u16
s32, u32
s64, s64
f32, f64 -- floating point 32-bit float or 64-bit double

So in my code in lieu of int I would use s32 or u32 depending on needs.
modern machines where it has 16 bits. unsigned int is allowed to have as
few as 16 bits, and there are real, modern machines where it is. You
should use uint8_t and uint32_t, respectively, from <stdint.h>. Those
are optional types, but it's rather unlikely that either of them is
unsupported. On any platform where either one is not supported, nothing
remotely similar to what you've written will work, so it's a good idea
to write your code in such a way that it would fail at compile time with
a diagnostic on such a platform.

By using s32, u32, and so on, I can need only change the header lines as
they exist in this file at/near the top:

https://github.com/RickCHodgin/libsf/blob/master/vvm/core/common/common.h
There's also another and much more plausible portability issue, which
you might be equally unconcerned about. Even assuming you are using
uint8_t[4] and uint32_t, there's still no guarantees about which bits in
u._color correspond to each element of u.color. In particular, there's
the big-endian/little-endian issue. If you need to port this code
between big-endian and little-endian machines, you'll need to decide
whether the byte order imposed by u.color or the bit order of u._color
is more important. I would expect the byte order of u.color is the
relevant one, and I'll use that assumption below.

My targets are x86 and ARM. They both support little endian. I doubt I
will ever support a big endian machine. And if I do, there are handful
of places where I can modify my code IF AND WHEN that ever happens.
In order to call foo() with defined behavior, you must pass it an object
of a type compatible with the unnamed type of u. Since that type is
unnamed, that is, in fact, extremely difficult (but possible) to
arrange. I wrote up a long explanation of why it was difficult, and how
it could be arranged, with the net conclusion that it makes much more
sense to give up your insistence that the union be anonymous. It is far
easier to make foo() usable if you give the union either a tag name or a
typedef.

I view the compiler as simply needing to create two references when it
sees a union like this:

void foo(SBGRA color)
void foo(int _color)

And then auto-insert code which populates the value, or simply recognizes
it as it is used within as through the union. I realize it does not do
this today, however, that's how I see it needing to be done.
However, after putting a lot of effort into that explanation, I realized
that it's probably irrelevant, because I'm almost certain that you don't
want to create an object of compatible type to pass to foo(). I suspect
that you want to pass either a struct SBGRA or an unsigned int to foo(),
possibly both, and neither of those types is compatible with the type of
u. You can't make anything like that work portably in C.

Understood. And I appreciate your efforts (FWIW).
There's probably many implementations where you could get it to work if
you use a K&R style declaration for foo() rather than a function
prototype, in any translation unit where foo() is called. Note that the
definition of foo() given above includes a function prototype:
therefore, if you wish to call foo() from later on within the same
translation unit where it is defined, you should change the definition
accordingly. I would not recommend that approach, but if you're
completely unconcerned with portability, go ahead and give it a try, it
might work (or it might not).

I have no desire for portability in many cases. It greatly increases the
workload for something that today does not exist in my plans at all. As
I have stated, I am planning to complete my RDC and I will support my
syntaxes without change on every platform I generate code for. As such,
portability is sort of "built in" in that regard. :)
The right way to do this is to pass around uint32_t values, and then
using constructs such as ((uint8_t*)color)[2] to access the red byte of
the object that it's stored in.

I view that as something that's absolutely non-intuitive and syntactically
clumsy. Using u.color.red makes sense.

I think actually in my compiler I would allow this:

void foo(union { SBGRA color, unsigned int _color })
{
printf("R:%u G:%u B:%u A:%u\n", color.red, color.grn, color.blu, color.alp);
printf("Color:%u\n", _color);
}

I would not require the "u" reference at all Both color and _color would
point to the same memory location on the stack.

Best regards,
Rick C. Hodgin
 
R

Rick C. Hodgin

For the record, it's official C11 syntax, so it can be accepted by
uptight compilers too.

I use Visual Studio 2008. It knows nothing of C11 syntax and must be
deriving these relaxations from its C++ nature, or Microsoft allowances.

Best regards,
Rick C. Hodgin
 
E

Eric Sosman

[...]
There are many contexts where you're prohibited from defining an
identifier that starts with '_'. This is NOT one of those contexts.
However, can you tell me precisely when it is safe to define such an
identifier? If not, I recommend avoiding them entirely, at least until
you've had time to memorize the relevant rules (section 7.1.3 of the C
standard).

I use them in all cases like this, and for global constants. All constants
in my systems are prefixed with an underscore, and are all caps. It's a
convention I picked up from my assembly days and have just kept.

So *all* your constants infringe on reserved name space?
How very jolly ...

Also, the fact that you did things one way in assembly
language -- or in Java or Ada or PL/I or COBOL -- is not a
good reason to do things the same way in C or Lisp or Fortran
or Lua or Perl.
 
K

Kenny McCormack

void main(void)

The return type of main must be int.[/QUOTE]

How about that "casting the return value of malloc()" thing?
How's that working out for you?
Many text books get this wrong, and many people write their code
accordingly, and as a result many compilers accept such code - those books
and those people are all ignoring what the C standard says.

Wrong. If a compiler documents that "void main()" is OK, then it is OK.

Compilers are allowed to extend the C standard.

The position held by the CLC religion, on this and many similar points, is
that "Well, you should always do it this way, because this way works all
the time [is guaranteed to work by the C standards documents] and the other
way(s) may not work [although they do work in almost all cases, so the
point is largely moot]". This is the normal "better safe than sorry"/"best
practices" position - and is held, religiously one might say, by, among
others, your good friend Kiki. Kiki is very good at limiting himself to
this position and not over-stepping by insisting that any other way is
categorically wrong. But, as we see in your case, it is very easy to go
too far and insist that "void main()" is wrong.

This sort of thinking is, incidentally, common to most major religions,
where what a small group of people think of as "best practice" is somehow
elevated to the status of "God's word".

--
The problem in US politics today is that it is no longer a Right/Left
thing, or a Conservative/Liberal thing, or even a Republican/Democrat
thing, but rather an Insane/not-Insane thing.

(And no, there's no way you can spin this into any confusion about
who's who...)
 
K

Kenny McCormack

Ben Bacarisse said:
For the record, it's official C11 syntax, so it can be accepted by
uptight compilers too.

And, more importantly in the context of this newsgroup, by uptight posters
as well.
 
R

Rick C. Hodgin

[...]
There are many contexts where you're prohibited from defining an
identifier that starts with '_'. This is NOT one of those contexts.
However, can you tell me precisely when it is safe to define such an
identifier? If not, I recommend avoiding them entirely, at least until
you've had time to memorize the relevant rules (section 7.1.3 of the C
standard).
I use them in all cases like this, and for global constants. All constants
in my systems are prefixed with an underscore, and are all caps. It's a
convention I picked up from my assembly days and have just kept.

So *all* your constants infringe on reserved name space?
How very jolly ...

Reserved in C/C++. My target is not C/C++, but RDC. It has been my target
since the mid-90s. I just haven't gotten there yet.
Also, the fact that you did things one way in assembly
language -- or in Java or Ada or PL/I or COBOL -- is not a
good reason to do things the same way in C or Lisp or Fortran
or Lua or Perl.

If not ... what is a good reason (given the constraints of: (1) it is
allowed today by the compiler, (2) it does not cause any issue with my
code in source or executable form, (3) my goals are RDC and not C/C++,
and (4) it becomes part of a standard throughout the toolchain
(anything with an underscore and all caps is a constant, and anything
with an underscore indicates it's not the real thing, but a reference
to something else as through a union))?

Best regards,
Rick C. Hodgin
 
J

James Kuyper

On 01/28/2014 08:27 PM, Rick C. Hodgin wrote:
....
I used it only to illustrate. I noticed in one of the coding examples
posted to me a void main(void) declaration. I had been using the ones
I am familiar with int main(int argc, char* argv[]) and it's a lot of
typing. So, for illustration I did the shorter version. :)

int main() is even shorter, and unlike void main(), it has defined
behavior on all hosted implementations of C.

....
I use them in all cases like this, and for global constants. All constants
in my systems are prefixed with an underscore, and are all caps. It's a
convention I picked up from my assembly days and have just kept.

Stop using that convention in C. C reserves some identifiers for the
implementation, and other identifiers for the users, in order to make
sure they don't interfere with each other. It is exactly analogous to
reserving one side of the road for northbound traffic, and the other
side for southbound traffic. To make the analogy exact, both sides of
the road are very wide, so what you're doing is less dangerous than
driving north in a southbound lane; but it's still an unnecessarily
dangerous thing to do.

Do you routinely drive on the wrong side of the road, too? If so, and
assuming that you survive long enough to be caught, would you tell the
police officer "That's OK, I'm planning to build my own road network
where all the streets allow you to go in either direction"? I don't
think the police officer would accept that explanation; neither would
the judge. I also don't think, if you ever get that road network built,
that there's many sane people who'd want to drive on it.

....
I view the compiler as simply needing to create two references when it
sees a union like this:

void foo(SBGRA color)
void foo(int _color)

That has nothing to do with the way C works today. It may be the way
that your new computer language will work, but this is not the best
forum for discussing code that relies upon it working that way.

....
workload for something that today does not exist in my plans at all. As
I have stated, I am planning to complete my RDC and I will support my
syntaxes without change on every platform I generate code for.

This is not the best place to discuss your plans for RDC. Why do you
persist in doing so?
 
J

James Kuyper

Reserved in C/C++. My target is not C/C++, but RDC. It has been my target
since the mid-90s. I just haven't gotten there yet.


If not ... what is a good reason (given the constraints of: (1) it is
allowed today by the compiler, (2) it does not cause any issue with my
code in source or executable form, (3) my goals are RDC and not C/C++,

Then don't discuss it here. Discuss it in a forum devoted to discussing
new languages. You'll find many people with similar interests in such a
forum, able to give you better advice than people in this forum.
 

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,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top