Syntax for union parameter

R

Rick C. Hodgin

That's a very long-winded way of saying practically nothing.

I just wanted to be sure we were on the same exact page. I know how
things can be taken or assumed out of their intended context in CLC. :)
If you
have an actual counterargument to my recommendation to use prototypes,
I'd be interested in seeing it; one of us might learn something.
(And it's actually about C.)

What if I don't? Will you think less of me? Actually I do ... so it's
a moot point. :)

Best regards,
Rick C. Hodgin
 
R

Rick C. Hodgin

Why would you ever want to use a non-prototype function declaration
or definition?


I wouldn't. I would just have the function definition itself prototype
the function on the second pass if it were, during the first pass, an
unknown at some point in source code.

Best regards,
Rick C. Hodgin
 
J

James Kuyper

What if I don't? Will you think less of me?

Of course - holding a strong opinion without good reasons is something
that we've come to expect of you, but holding a strong opinion with no
reason at all is still something that can (very marginally) reduce our
opinion of you.
 
J

James Kuyper

I wouldn't. I would just have the function definition itself prototype
the function on the second pass if it were, during the first pass, an
unknown at some point in source code.

But that IS using a prototype. It's not following precisely the C rules
for the scope of function prototypes, but those rules are not as
important as the function prototypes themselves. Valid C code that never
uses non-prototype declarations would compile the same way under your
rule as under C rules.
 
J

James Kuyper

... "I couldn't disagree more. But, I'll save that argument for another day."

I did a lot of programming in K&R C back before prototypes were widely
implemented, and even before they were first added to the language.
Prototypes make it mandatory for the compiler to detect as mistakes many
things that were permitted in K&R C, and almost without exception, every
single program I've ever converted to use prototypes produced
diagnostics after the conversion. Those diagnostics were almost always
about real problems in the code that had previously gone undetected,
very few of them were just about fussy details of the new rules for
prototypes.

I can't imagine clearer proof of the fact that you don't have the right
attitudes to use a language like C, than the fact that you don't approve
of prototypes. You're firmly stuck in an assembly-language mindset, and
are so certain that you're right that you're completely rejecting the
advice of people with more experience than you in higher level languages.
 
K

Keith Thompson

Rick C. Hodgin said:
I wouldn't. I would just have the function definition itself prototype
the function on the second pass if it were, during the first pass, an
unknown at some point in source code.

Please re-read the part where I explained what a prototype is.

A function *definition* also provides a function *declaration*.

It does so only *after* the appearance of the declaration; your remarks
about two-pass compilation must be about some language other than C.

A non-prototype function declaration or definition uses empty
parentheses for the parameter portion. All I'm saying is that
there's no good reason to use that obsolescent syntax. I would
not write:

int func() { /* ... */ }

(even though it's still legal). Rather, I would write:

int func(void) { /* ... */ }

I don't believe you actually disagree with that, though you said you did.

This is not about using or not using "forward" declarations. It's about
which form of declaration to use.

As of C99, calling a function with no visible declaration is a
constraint violation, even if a declaration occurs later in the source.
If a C compiler accepts something like:

int main(void) {
func(42);
}

void func(int n) { /* ... */ }

it's (almost certainly) not because it does a second pass that
recognizes the later declaration/definition. It's because it's
following pre-C99 rules that permit calls to undeclared functions. A
typical compiler would also accept a call `func()`, `func("hello")`,
or `func(1.23)` with no warning, and would generate incorrect code.
In the last case, it would not implicitly convert 1.23 from double
to int, as it would if the declaration were visible.
 
B

BartC

Non-prototype function declarations and definitions are an
obsolescent feature that could be removed in a future edition of
the C standard.

Using non-prototype declarations runs a considerable risk of writing
a function call with the wrong number or type(s) of arguments,
and not having the compiler catch it. Sure, a sufficiently clever
compiler could warn you about it, but it would be foolish to count
on that.

I first learned C before prototypes were added to the language.
When I accidentally wrote a call that passed the wrong number of
arguments to a function, I was horrified that the compiler didn't
diagnose it.

Let's be sure that you know what the word means. A prototype is
a function declaration that specifies the type(s) of the parameters.

I can think of no good reason to use non-prototype declarations
or definitions. (Saving a few characters is not IMHO a good reason.)

Why would you ever want to use a non-prototype function declaration
or definition?

You've confused me know with this post.

Whatever the official meaning of prototype, what I (and I think Rick) take
to be function prototypes are a separate set of declarations which declare
the names, numbers and types of parameters, and return types of functions
defined elsewhere. In the case of local functions, later on in that file.

Take the C code I posted elsewhere in the thread, which I said was
code-generated. Take out the prototype declarations, and it will give a
compile error, especially if you rearrange the function definitions. Those
separate prototypes are necessary (at least, in the compiler I use), unless
you arrange the definitions in a certain order.

The problem is this means declaring many things twice, and that leads to
maintenance issues.

Rick is right in that the need for prototypes can easily be eliminated (in
the input source code), which is exactly what I've done in the C
preprocessors, and translators to C, that I've worked on. Of course the
generated C (and associated headers for things that are exported) needs to
have those inserted, but it's no longer a programmer responsibility.
 
J

James Kuyper

My responses are when I'm asked why I do this or that.

That's pretty normal; responses generally do occur (if at all) after the
thing that they're responses to. It doesn't explain why you're
discussing RDC here rather than in a more appropriate forum. You would
get a more appreciative audience and more useful advice in such a forum.
I can only conclude that you don't mind annoying people, and are not
particularly interested in getting useful advice.
 
R

Rick C. Hodgin

Please re-read the part where I explained what a prototype is.

A function *definition* also provides a function *declaration*.

I agree with this part.
It does so only *after* the appearance of the declaration; your remarks
about two-pass compilation must be about some language other than C.

Today it must come before use ... and that's my point. There's no reason
for that except some throwback to the days when computers were far weaker
than they are today.
A non-prototype function declaration or definition uses empty
parentheses for the parameter portion. All I'm saying is that
there's no good reason to use that obsolescent syntax. I would
not write:

I would never use empty parenthesis. I would also declare void (so
as to indicate my intention was to not have any parameters).
int func() { /* ... */ }
(even though it's still legal). Rather, I would write:
int func(void) { /* ... */ }
I don't believe you actually disagree with that, though you said
you did.

I do indeed agree wholeheartedly on that point.
This is not about using or not using "forward" declarations. It's
about which form of declaration to use.
Agreed.

As of C99, calling a function with no visible declaration is a
constraint violation, even if a declaration occurs later in
the source.

This is the part I disagree with. It's running backwards with regards
to technology. In fact, I would go so far as to say that the if the
function prototype definition were needed, as part of an external
reference so as to be used in a file compiled separately and linked
in later, that some combination of the compiler and IDE should auto-
generate it.
If a C compiler accepts something like:
int main(void) {
func(42);
}

void func(int n) { /* ... */ }

it's (almost certainly) not because it does a second pass that
recognizes the later declaration/definition. It's because it's
following pre-C99 rules that permit calls to undeclared functions.
A typical compiler would also accept a call `func()`, `func("hello")`,
or `func(1.23)` with no warning, and would generate incorrect code.
In the last case, it would not implicitly convert 1.23 from double
to int, as it would if the declaration were visible.

I do not believe compilers should generate incorrect code. If there is
a problem in the code, it should automatically compile something in
which allows it to run up until it gets to the part which was in error
as per source code, and then trigger some standard method of trapping
to the debugger, or presenting output to an abort log.

We are moving forward with hardware, not backwards. More memory, more
CPUs, larger disk capacities, and this means we can now handle the
entire project in memory at the same time. I saw where 16GB of RAM
could be purchased for a few hundred dollars recently.

I will accept that C works as it does. It is insufficient for a language
of the 2010s in my opinion. My arguments against it relate not to it
being a fine, working, long used language of well renown, but rather to
it being designed with specific goals in mind which are constricting,
rather than freeing.

I'll gladly resign from this conversation because my views are not related
to C, but rather what C should've been (in my opinion), based on the 2000+
direction of hardware abilities.

Best regards,
Rick C. Hodgin
 
J

James Kuyper

On 01/29/2014 12:49 PM, BartC wrote:
....
Whatever the official meaning of prototype, what I (and I think Rick) take
to be function prototypes are a separate set of declarations which declare
the names, numbers and types of parameters, and return types of functions
defined elsewhere.

No, that's not consistent with the "official meaning of prototype".
Function declarations can indeed be separate from the function
definition, as you describe, and that is normally the case for most
function declarations that occur in a header. However every function
definition also starts with a function declaration - that's the part
prior to the '{' that marks the start of the function body. Function
declarations can use either K&R syntax (though in C99 they're no longer
allowed to rely upon implicit int) or prototype syntax. I strongly
prefer the latter; Rick claims to disagree, though possibly as a result
of having the same misunderstanding as you've just expressed.

Take the C code I posted elsewhere in the thread, which I said was
code-generated. Take out the prototype declarations, and it will give a
compile error, especially if you rearrange the function definitions. Those
separate prototypes are necessary (at least, in the compiler I use), unless
you arrange the definitions in a certain order.

If you do rearrange the definitions in that order, it will work without
any function declarations other than the ones that come built-in to the
function definition. That isn't always the case: a recursion loop will
require the declaration of at least one function prior to it's
definition, but that's a fairly unusual case. I normally do rearrange
purely local functions, when possible, so that separate declarations are
unnecessary. This means that you won't see a call to a local function
until after you've seen the function's definition, which strike me as a
very logical way to organize the code. Opinions differ on this issue.
Rick is right in that the need for prototypes can easily be eliminated (in

The need for separate prototypes can be eliminated - but eliminating the
prototypes that come built-in to the function definitions would NOT be a
good idea.
 
S

Stephen Sprunk

You're ... so certain that you're right that you're completely
rejecting the advice of people with more experience than you ...

Did you expect any better from a religious zealot?

S
 
J

James Kuyper

Did you expect any better from a religious zealot?

Religious zealotry and computer language zealotry are distinguishable;
but I will grant you that they can be somewhat correlated.
 
B

Ben Bacarisse

BartC said:
Whatever the official meaning of prototype, what I (and I think Rick) take
to be function prototypes are a separate set of declarations which declare
the names, numbers and types of parameters, and return types of functions
defined elsewhere. In the case of local functions, later on in that
file.

You are right about what is being said. Rick, and it seems you, think
of prototypes as something they are not -- you attach the name only to
separate declarations (often "forward" declarations) of functions.

The trouble is that the word has a meaning in C and its deeply ingrained
in many people's minds (at least it is in mine). Having spent a decade
programming without them, when prototypes come along the meaning is very
clear.

tl;dr: I a C group, it really helps to use C terms.
Take the C code I posted elsewhere in the thread, which I said was
code-generated. Take out the prototype declarations, and it will give a
compile error, especially if you rearrange the function definitions. Those
separate prototypes are necessary (at least, in the compiler I use), unless
you arrange the definitions in a certain order.

The problem is this means declaring many things twice, and that leads to
maintenance issues.

Rick is right in that the need for prototypes can easily be eliminated (in
the input source code),

He's not shown that yet. What about prototype declarations of external
functions? Yes, using the C meaning you don't need a prototype -- you
just write empty brackets -- but using his apparent meaning, prototypes
are still needed in this case.

<snip>
 
S

Stephen Sprunk

Religious zealotry and computer language zealotry are
distinguishable; but I will grant you that they can be somewhat
correlated.

Well, both are characterized by obsession with dogma over reality at
times, but the language zealotry here seems to be surprisingly limited.

S
 
B

Ben Bacarisse

James Kuyper said:
The need for separate prototypes can be eliminated - but eliminating the
prototypes that come built-in to the function definitions would NOT be a
good idea.

I think they are still needed for functions whose definitions are not
visible to the compiler -- roughly speaking external functions.
 
R

Rick C. Hodgin

He's not shown that yet. What about prototype declarations of external
functions? Yes, using the C meaning you don't need a prototype -- you
just write empty brackets -- but using his apparent meaning, prototypes
are still needed in this case.

There are cases where it is more advantageous to have prototype declarations,
such as these examples you state. If I am compiling something that will be
linked in later, then it may not be desirable to parse the entire source file
to obtain the function declarations as prototypes themselves. As such, the
need for those prototype declarations are desirable.

Still, there should be no reason any human being has to write them in any
case. The compiler can parse the function declarations and create the
prototype file as a mechanical operation of the compiler, rather than of
the developer. Compilers won't make mistakes once they're coded and
debugged. People will.

And for systems which are integrated using the tools available today as
they relate to hardware, there is no longer any reason whatsoever for
any human being to maintain any aspect of mechanical conveyance of
something internal to an application. The computer's entire existence
is to help man increase productivity. I am not well served by doing
lots of mechanical typing when the computer itself can, through multiple
threads on multiple cores with gigabytes of memory, re-parse the entire
source code file of the Linux kernel, for example, in near real-time.

The fact is C looks backwards, to a time when machines were limited.
There are MANY facets of C that should be revisited, and the cojoined
nature of the advanced edit-and-continue C compiler and IDE should be
acknowledged as the future.

My opinion. C needs to change. I will actually introduce a C compiler
at some point into my RDC toolchain. This will allow existing code to
be compiled properly, along with the extensions I'll add. As such, I
hope to bring this forward to people as well. The only reason I'll be
doing it is because I recognize the code base that's out there and that
there are needs to not lose those man-hours when the machine can fill
in the gap between where things are and where they should be.

Best regards,
Rick C. Hodgin
 
B

BartC

Ben Bacarisse said:
He's not shown that yet. What about prototype declarations of external
functions? Yes, using the C meaning you don't need a prototype -- you
just write empty brackets -- but using his apparent meaning, prototypes
are still needed in this case.

Let's call these forward declarations rather than prototypes.

In C as it is now, they would still be needed, for external and some local
functions (the legacy of C allows you to get away without some of them, but
that is too lax in my view).

However, in a tweaked version of C, or this new 'RDC', they can be
eliminated. In the C syntax wrappers I've worked on, they largely have been.

(In the case of my input source code, the not-quite-C syntax requires that
exported functions have a 'global' prefix; all others are local (generated
with 'static' later on), which is a different default to C.

Local functions have their forward declarations written to the top of the
generated C. Exported ones are written to an associated header file. This
header file is included by modules that want to make use of the exported
names. (And the same mechanism deals with local and exported variables,
named constants, enums and types.)

So the forward declarations are still needed because an actual C compiler is
used, but their generation can be automated. (Although it doesn't work well
for mutually imported modules, that hasn't been a problem so far, and it's
always possible to use conventional declarations.))
 
R

Rick C. Hodgin

I think they are still needed for functions whose definitions are not
visible to the compiler -- roughly speaking external functions.

I concur. In the alternative, let their use be determined by context and
let the linker perform any necessary fixups should the definition itself
not be available. I don't see this as a reasonable case for an error, but
rather only for a warning. Not having the external prototype definition
should not prevent code that is otherwise syntactically correct from
compiling. It should generate a warning that there is the unknown, and if
the linker can't find it then report an error because at that time it is
a true unknown.

These points are made moot if the source is brought into a project which
can manage all functions as tokens with their indicated parameters.

Oh, and I further believe C should've had multiple return parameters.
RDC will allow this type of syntax:

[int x, int y] foo(int a, int b)
{
x = a;
y = b;
// No need for "return(a,b)" as I can directly populate the variables
}

And I'm actually considering allowing also all parameters to be explicit:

function foo
|Returns int x // They can be broken out on separate lines with comments
|Returns int y
|Params int a, int b // Or they can be on the same line
{
// Function body goes here
}

I also believe in ad hoc functions:

int main(void)
{
printf("Welome to the adhoc example.\n");

// Adhoc functions are functions declare near where they
// are used, but they are skipped over by normal program
// flow, and are merely a way to make the code more clear,
// or to put code used in a particular place where they
// are used.
adhoc int square(int x)
{
return x * x;
}

printf("Square of 3 is %u\n", square(3));
}

Best regards,
Rick C. Hodgin
 
J

James Kuyper

I think they are still needed for functions whose definitions are not
visible to the compiler -- roughly speaking external functions.

The claim he appears to be making, and it seems a valid one, is that
with a very different approach to such things than the one taken by C,
it would be possible for the declaration that is part of the function
definition to literally BE the declaration that is visible when
compiling calls to that function from another module (or perhaps he's
simply abondoning the idea of breaking large programs into separate
modules?).

That would rule out independent compilation of modules - the module that
defines a function would have to compiled along with the module where it
is called, or the compiler would not be possible to validate that the
function was called correctly. The closest you could get to true
separate compilation would be to start out with empty function bodies
for the functions that are being called, but haven't been completely
written yet. That seems clumsier than the current approach, but it would
avoid having to provide two different declarations for the same function.
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top