Syntax for union parameter

B

BartC

Ben Bacarisse said:
Right. I take it the "!" means joke?

No. The forward declarations, /in C as it is now/, seem to like being at the
beginning. In C as it could be, they are not really needed (actually I'm not
sure why they are needed now, for functions within the same file).

So what has that to do with my point?

OK. Forget everything that's been said so far.

Is is possible to tweak C so that function declarations, separate from
definitions, can be eliminated? That is, so that a programmer writes just
the definition, and that's it?

I'm not sure if you're saying yes or no. Obviously no as C now is, but I'm
saying it's possible and so was Rick.
 
B

BartC

James Kuyper said:
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's the same claim I'm trying to make (and not really succeeding). But
I've also done it. My approach however is not to eliminate the conventional
declarations that are needed, but to generate them automatically. You get
the same advantage in only having to write the definition.
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.

Yes, it's necessary to first compile the file that contains the functions
that will be used in another, but so what? They must be compiled at some
point! Although the bodies can initially be empty. But that is only my
approach, there are many ways to do this.

And if you have a file A that is using some functions in file B, and the two
are remote, written by different people, etc, then file B needs to be
compiled, or have something done to it, to yield the information needed by A
(as I do it, the special processing yields the file B.h that can be
distributed to the owner of A; the source remains private.)

The important thing is that it works; I've hardly written a separate
declaration, in real code, since about 2012.
 
B

Ben Bacarisse

BartC said:
OK. Forget everything that's been said so far.

I'll go for that.
Is is possible to tweak C so that function declarations, separate from
definitions, can be eliminated? That is, so that a programmer writes just
the definition, and that's it?

I'm not sure if you're saying yes or no. Obviously no as C now is, but I'm
saying it's possible and so was Rick.

I'm saying no. Not that there is no conceivable language that does not
have them, but that anything that is to fit the same sort of niche as C
needs something like it. In such a language, if you want to use an
external function whose code is not available, something is needed to
tell the implementation how to type-check the call.

Languages like B and BCPL get away without these "typed declarations"
simply because they have no type checking. Some languages with run-time
types get away with it for a similar reason but they can be type-safe
none the less. A language that is at all C-like (no run-time types, but
with a useful amount of type checking) needs something to work with.
 
B

BartC

(I spent 25 years doing this! Striving to keep duplicate declarations of
thousands of functions up to date with each other. There must be a better
way.)

Yes, it's crazy.
I'm sure a tool could be written that would take a .c file containing a
set of function definitions, and automatically generate a corresponding
.h file. I'd be quite surprised if such a tool doesn't already exist.

Now you're getting it. I've been using such tools of my own for the last
year and a half, and they work great. (The tools also tweak the syntax, but
that's just my preference.)
What you seem to be advocating is a different change to the language,
allowing function declarations and calls to appear out of order and
still be checked. (Is that about right?) Neither pre-1999 C nor
post-1999 C supports this feature. (I personally am not thrilled about
the idea, since we have ways to avoid the need for out-of-order
declarations.)

You mean, sorting 700 functions in a file according to their calling
hierarchy? Yes, sure! If people have clever IDEs that can take care of those
details, that's fine, but then everyone is in reality using the their own
ad-hoc extensions, rather than evolving the base language in useful ways.
 
B

BartC

Ben Bacarisse said:
I'm saying no. Not that there is no conceivable language that does not
have them, but that anything that is to fit the same sort of niche as C
needs something like it. In such a language, if you want to use an
external function whose code is not available, something is needed to
tell the implementation how to type-check the call.

Languages like B and BCPL get away without these "typed declarations"
simply because they have no type checking. Some languages with run-time
types get away with it for a similar reason but they can be type-safe
none the less. A language that is at all C-like (no run-time types, but
with a useful amount of type checking) needs something to work with.

My reply to James (29/01/2014 23:58, but that might be GMT) explains a
different way how I try and do it, and still provide full type-checking.
 
R

Rick C. Hodgin

No, read that again: "Any ".c" file that either defines..". Always
include the header with the prototype declaration in the source file
with the function definition.

Yes. My code was in a .cpp file, so it was passed over by the compiler.
My mistake.
Alas, compilers aren't psychic yet.

My point is that *I'M* doing this work, rather than the compiler
generating any such files for me.
If it was never used, you wouldn't have had a problem with it, would
you?

That is what had happened for some time (months).
Don't you consider defining a function "use"? If you had followed
the convention, the definition would have cased an error.

I did follow the convention, but the Visual C++ compiler compiling
my code does not reconcile mismatched function declarations in .h
and .cpp files.
That somewhere should have been in a header included everywhere the
function was called or defined. End of problem.

This seems to only be true in a .c file. I tested this when I got home
writing these two files:

-----tst.h-----
#include <stdio.h>
#include <stdlib.h>

int foo(int a);
------end------

-----tst.c-----
#include "tst.h"

int main(int argc, char* argv[])
{
printf("Hi, mom!\n");
return(0);
}

int foo(float a)
{
printf("%f\n", a);
}
------end------

Using "gcc tst.c" it reported these errors:
tst.c:9:5: error: conflicting types for 'foo'
In file included from tst.c:1:0:
tst.h:6:5: note: previous declaration of 'foo' was here

Using the same source files, but renaming tst.c to tst.cpp, and
using "g++ tst.cpp" it compiles without error.

I again apologize for my ignorance with regards to what is C and
what is C++, or what is a C standard, and what is an extension
as per Microsoft's extensions in Visual C++.

Best regards,
Rick C. Hodgin
 
I

Ian Collins

Rick said:
Yes. My code was in a .cpp file, so it was passed over by the compiler.
My mistake.

Well if you will insist on using a C++ compiler, you can't complain
about deficiencies in C...
That is what had happened for some time (months).

That wouldn't have happened if you'd written tests first!
I did follow the convention, but the Visual C++ compiler compiling
my code does not reconcile mismatched function declarations in .h
and .cpp files.

Because it's using the C++ rules for function overloading.

Using "gcc tst.c" it reported these errors:
tst.c:9:5: error: conflicting types for 'foo'
In file included from tst.c:1:0:
tst.h:6:5: note: previous declaration of 'foo' was here

Using the same source files, but renaming tst.c to tst.cpp, and
using "g++ tst.cpp" it compiles without error.

If you are going to be compiling with a C++ compiler, you really should
become familiar with the differences between the two languages.
I again apologize for my ignorance with regards to what is C and
what is C++, or what is a C standard, and what is an extension
as per Microsoft's extensions in Visual C++.

Double check with a C compiler in conforming mode, or read the standards!
 
R

Rick C. Hodgin

Well if you will insist on using a C++ compiler, you can't complain
about deficiencies in C...

On the contrary ... I can most certainly complain about deficiencies
in C ... just not for those reasons. :)
That wouldn't have happened if you'd written tests first!

It also wouldn't have happened if there were no need for forward
prototypes.
Because it's using the C++ rules for function overloading.

Agreed. :)
If you are going to be compiling with a C++ compiler, you really should
become familiar with the differences between the two languages.

I don't care to learn such things. It's a bunch of learning about...
whatever... and with RDC I am taking features I like from both and
bringing them together ... so it would be counter-productive.
Double check with a C compiler in conforming mode, or read the standards!

No thanks. Too much work for nothing valuable in return. I can simply
write code and let the compiler authors worry about such things. When
I encounter a problem, then I can correct it, code around it, or do a
search at that time to figure out the cause. :)

Not having forward prototypes still would've prevented this problem.

Best regards,
Rick C. Hodgin
 
K

Keith Thompson

BartC said:
Is is possible to tweak C so that function declarations, separate from
definitions, can be eliminated? That is, so that a programmer writes just
the definition, and that's it?

I'm not sure if you're saying yes or no. Obviously no as C now is, but I'm
saying it's possible and so was Rick.

Is it possible? I suppose so.

Within a single source file, a compiler could perform two passes over
the source, collecting function declarations on the first pass and
doing normal compilation on the second (or some variant of that).
Just as a feasibility demonstration, the first pass could generate
function declarations, write them to a temporary file, and then
copy the source to the end of the temporary file; the second pass
could be an ordinary C compiler applied to the temporary file.
No doubt there are more efficient ways to do the same thing.

The problem is separate compilation. Suppose I want to use a
function defined in some library, say mpz_init() (which happens to be
part of the GNU multiprecision arithmetic library). The definition
of mpz_init is in some source file. You suggest not having a
separate declaration anywhere.

Currently, if I want to write code that calls mpz_init(), all I
need are the library that implements it (say, libgmp.so or libgmp.a)
and the header file that declares it (say, /usr/include/gmp.h).

In your scheme, how does the compiler know how the function
is declared? Do I have to have a copy of the full source file?
C is carefully designed to avoid that need. (In the case of GMP,
it's merely a convenience; in the case of non-free / non-open-source
software, it's potentially critical.)

And if the declaration defining the interface to the function exists
only in the source file that defines it, and I update some minor
detail of the implementation, how will my build system know that
the interface hasn't actually changed and all my client code doesn't
need to be recompiled? I suppose that *could* be done by some tool
that keeps track of whether a given change to the source file changed
the interface in some significant way, but keeping declarations and
definitions in separate files is a much easier way to manage that.
 
K

Keith Thompson

Rick C. Hodgin said:
Yes. My code was in a .cpp file, so it was passed over by the compiler.
My mistake.

Well there's your problem. .cpp is the conventional suffix for a C++
source file, not a C source file. (If you're interested, comp.lang.c++
is down the hall on the left, just past the water cooler.)

[...]
That somewhere should have been in a header included everywhere the
function was called or defined. End of problem.

This seems to only be true in a .c file. I tested this when I got home
writing these two files:

-----tst.h-----
#include <stdio.h>
#include <stdlib.h>

int foo(int a);
------end------

-----tst.c-----
#include "tst.h"

int main(int argc, char* argv[])
{
printf("Hi, mom!\n");
return(0);
}

int foo(float a)
{
printf("%f\n", a);
}
------end------

Using "gcc tst.c" it reported these errors:
tst.c:9:5: error: conflicting types for 'foo'
In file included from tst.c:1:0:
tst.h:6:5: note: previous declaration of 'foo' was here

Using the same source files, but renaming tst.c to tst.cpp, and
using "g++ tst.cpp" it compiles without error.

That's to be expected.

In C, these functions:
int foo(int a);
and
int foo(float a);
cannot coexist in the same program (unless they're static).

In C++, they can simply be two distinct functions. It's called
overloading. In C++, it's not a mismatch.

If you had followed the conventions I described earlier *and compiled
your C source code as C*, then the compiler would have diagnosed the
mismatch.

(Just curious: if you're trying to write C code, why would you give the
source file a .cpp suffix?)
 
R

Rick C. Hodgin

(Just curious: if you're trying to write C code, why would you give the
source file a .cpp suffix?)

When I began this project (writing Visual FreePro) in 2009, it was in C++.
I later decided to switch back to C because I wanted to pursue my goals of
the RDC toolchain as part of that project. From 2009 through 2012 I was
planning on C++. After that I have been planning on RDC.

RDC will have some aspect of C++, including some aspects of the class.
But it will not be fully C++. It will be much more C-like using some
C++ syntax.

Best regards,
Rick C. Hodgin
 
J

James Kuyper

On the contrary ... I can most certainly complain about deficiencies
in C ... just not for those reasons. :)

Nothing stops you from complaining about anything you want; but
complaining about non-existent problem with C that's due to the fact
that you actually compiled the code with a correctly working C++
compiler makes you look ridiculous.

C, C++, and RDC are three different languages. When what you're saying
is really about C, it's fine to post it here. But if you're actually
talking about C++, the more appropriate place is comp.lang.c++ (or for a
better signal-to-noise ratio, comp.lang.c++.moderated). Someone else has
already told you the appropriate location for discussing RDC.

....
I don't care to learn such things. It's a bunch of learning about...
whatever... and with RDC I am taking features I like from both and
bringing them together ... so it would be counter-productive.

Learning more about particular languages - well-established and popular
languages - that you are deliberately borrowing features from while
creating you own language - would be counter-productive? I think you're
measuring your productivity incorrectly.
 
J

James Kuyper

You mean, sorting 700 functions in a file according to their calling
hierarchy?

Putting 700 functions in a single file was probably a mistake; even
putting 700 lines in a single file is often a mistake. When you only
define a reasonable number of functions per file, sorting them by their
calling hierarchy is no big deal.
 
G

Geoff

I again apologize for my ignorance with regards to what is C and
what is C++, or what is a C standard, and what is an extension
as per Microsoft's extensions in Visual C++.

It's really great that you are building a compiler that's a little
like C and a little like C++ and you have no real understanding of the
formal specifications of either of those languages and that you can
base all your knowledge of "C and C++" on Visual Studio, a compiler
that is deliberately stuck at C'89 and nowhere near C++'11. I'm sure
your compiler will benefit from it.
 
K

Kaz Kylheku

I don't care to learn such things. It's a bunch of learning about...
whatever... and with RDC I am taking features I like from both and
bringing them together ... so it would be counter-productive.

Why would I use this RDC, when its author is willfully ignorant about workign
out the difference between C and C++, or what is dialect and what is standard?
No thanks. Too much work for nothing valuable in return. I can simply
write code and let the compiler authors worry about such things. When

What does that even mean, "let the compiler authors worry about such things"?

Are you planning on sending your code to the compiler authors to fix?

A sentence in the form "let person X worry about Y" generally indicates
that the speaker is passing responsibility to X; X is expected to take
some action, to resolve problems related to Y.

What is it that the compiler writers worry about, and how does it help you,
if you don't care to look at the documents that their work is based on?
I mean, whether they do something right, or wrong, by their design or
by the spec, you can't possibly care, because you choose not to know.
You choose not to know whether something you coded works by design or accident.

Now, a compiler author is what you're trying to be, with this RDC, right?

Aren't you going to have a an accurate, complete reference manual for RDC that
is kept up to date with every public release?

Or will you expect your users to program by trial-and-error, as you do,
and to "port" their programs to each release of RDC by trial-and-error?

When someone reports a behavior (in particular, a change in behavior), by what
method will you determine whether it is a bug, or whether it is an invalid
report?

Not having a precise, standard-like document will let you just wave your hands
and say, "well, that was never written down anywhere, too bad for you!"

Or maybe the user really is wrong, but to provide good support, you will just
cave in and make the stupid behavior work again, not being able to point to the
any precise requirement spec which makes it right or wrong.

Are you sure you can do a good job specifying a programming language, if you
don't bother reading such documents written by others? And where will the
motivation come from to write specs, if you don't read such twaddle?
 
K

Kaz Kylheku

I again apologize for my ignorance with regards to what is C and
what is C++, or what is a C standard, and what is an extension
as per Microsoft's extensions in Visual C++.

Pop quiz.

Suppose that array int a[] contains { 1, 2, 3 }, and int i is 0.

After the execution of a = a[i++], what should be the values in a[]?

Why?
 
G

glen herrmannsfeldt

Keith Thompson said:
(snip)

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.

Well, that is what lint was supposed to do. If you ran it often
enough, it would find all those bugs. Of course no-one ran it
quite often enough.
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.

Being used to Fortran 66 before C, I wasn't surprised at all.
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.)

Yes they do make some bugs harder. Still, I remember when they were
new, and I added them to my program, at which point it failed.

I believe related to function arguments of type float.
Why would you ever want to use a non-prototype function
declaration or definition?

Maybe for programs that are less than 10 lines long.

-- glen
 
B

BartC

Keith Thompson said:
Is it possible? I suppose so.
The problem is separate compilation. Suppose I want to use a
function defined in some library, say mpz_init() (which happens to be
part of the GNU multiprecision arithmetic library). The definition
of mpz_init is in some source file. You suggest not having a
separate declaration anywhere.

No, I'm suggesting not having to sit down and write the separate declaration
yourself; it would be automatic.
Currently, if I want to write code that calls mpz_init(), all I
need are the library that implements it (say, libgmp.so or libgmp.a)
and the header file that declares it (say, /usr/include/gmp.h).

Sure; for a system which is very close to C, or which is implemented on top
of current C (C99, C11 etc) the header file would still exist, it's just
that *no-one has to manually create it*.

I mean, it can't be the most difficult programming task to scan a .c source
file, pick up the function declarations that are exported (the ones without
a static attribute), and write out those declarations to a .h file, but
sticking a ";" at the end of each instead of having "{" there.
In your scheme, how does the compiler know how the function
is declared?

Because gmp.h will be distributed by the writers/maintainers of the library.
If the source changes, then they provide a new gmp.h, and a new binary. Of
course, since it is an external library, you will have no knowledge of
exactly how that gmp.h file came into existence, and will not care. (And for
all you know, perhaps various tools have already been used to put it
together.)

(A scheme as I've suggested works best where source modules have a simple
dependency tree, as happens when you have external libraries which are not
going to directly call your code. It doesn't work well when module A calls
functions in B, and module B calls functions in A.

Also, if there are changes to many modules at the same time, then you might
need to be careful in which order they are compiled, although this can be
also be automated. So there are some difficulties, but as I said elsewhere,
since I implemented my scheme in 2012, I can hardly remember having to worry
about prototypes in headers.)
Do I have to have a copy of the full source file?
No.

And if the declaration defining the interface to the function exists
only in the source file that defines it, and I update some minor
detail of the implementation, how will my build system know that
the interface hasn't actually changed and all my client code doesn't
need to be recompiled?

When you recompile a module, it updates the associated header file.
I suppose that *could* be done by some tool
that keeps track of whether a given change to the source file changed
the interface in some significant way, but keeping declarations and
definitions in separate files is a much easier way to manage that.

No, it isn't. Easier to implement perhaps, but then the onus is on somebody
(you or me) to make sure the declarations correctly track any changes in the
definition file.
 
B

BartC

James Kuyper said:
Putting 700 functions in a single file was probably a mistake; even
putting 700 lines in a single file is often a mistake. When you only
define a reasonable number of functions per file, sorting them by their
calling hierarchy is no big deal.

OK, not 700, but it could be any number. Looking at some of my code, one
file has 276 functions (because it depends heavily on inlining), although
they rarely call each other.

Another has 80, most with names that start with the same three letters. And
when I'm editing one function, I have no idea where it is located in
relation to any of the others. And I shouldn't need to know (C is supposed
to free-format).

I could write a better editor, but wouldn't it be better to just fix the
language? Certainly, there is no reason in 2014 for separate local function
forward prototype declarations (just to make it clear what I mean!) to be
necessary.
 
B

BartC

Rick C. Hodgin said:
When I began this project (writing Visual FreePro) in 2009, it was in C++.
I later decided to switch back to C because I wanted to pursue my goals of
the RDC toolchain as part of that project. From 2009 through 2012 I was
planning on C++. After that I have been planning on RDC.

RDC will have some aspect of C++, including some aspects of the class.
But it will not be fully C++. It will be much more C-like using some
C++ syntax.

Probably a good thing. I read that writing a C++ compiler requires ten
man-years of effort (and an Ada one apparently fifty years(!)).
 

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
474,079
Messages
2,570,574
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top