Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

const and struct pointers

2 views
Skip to first unread message

Charles Hannum

unread,
Feb 23, 1990, 11:23:25 PM2/23/90
to

The double is passed by value; so dereferencing it works fine. But the
struct is passed by reference (as are *all* structures in C!). In reality,
you need to pass a "struct qwert *" to the function. Normally, the compiler
takes the reference automatically, but you are trying to do this in reverse.
Thus, it does not work; you simply can't pass a structure by value.


Virtually,
- Charles Martin Hannum II "Klein bottle for sale ... inquire within."
(That's Charles to you!) "To life immortal!"
cmh117@psuvm.{bitnet,psu.edu} "No noozzzz izzz netzzzsnoozzzzz..."
c9h@psuecl.{bitnet,psu.edu} "Mem'ry, all alone in the moonlight ..."

Randy Hutson

unread,
Feb 24, 1990, 7:36:00 AM2/24/90
to

In message <90054.232...@psuvm.psu.edu> CMH...@psuvm.psu.edu
(Charles Hannum) writes:


>The double is passed by value; so dereferencing it works fine. But the
>struct is passed by reference (as are *all* structures in C!). In reality,
>you need to pass a "struct qwert *" to the function. Normally, the compiler
>takes the reference automatically, but you are trying to do this in reverse.
>Thus, it does not work; you simply can't pass a structure by value.

The original poster said his compiler claimed to be ANSI compliant. ANSI
C allows structures to be assigned, returned by functions, and passed by
value to functions. However, some non-ANSI compilers may do as you have
said with struct function arguments.

Will Crowder

unread,
Feb 24, 1990, 1:15:26 PM2/24/90
to
In article <90054.232...@psuvm.psu.edu> CMH...@psuvm.psu.edu
(Charles Hannum) writes:
>
>The double is passed by value; so dereferencing it works fine. But the
>struct is passed by reference (as are *all* structures in C!). In reality,
>you need to pass a "struct qwert *" to the function. Normally, the compiler
>takes the reference automatically, but you are trying to do this in reverse.
>Thus, it does not work; you simply can't pass a structure by value.

Uh, yes you can. The man is using what claims to be an ANSI C compiler
(apparently, a slightly broken one), and there is nothing special about
structure objects in ANSI C (at least in terms of how they are passed to
a function).

From 3.1.2.5 of the 12/88 draft:

"Any number of derived types can be constructed from the object,
function, and incomplete types, as follows:"
...
"* A structure type describes a sequentially allocated nonempty
set of member objects, each of which has an optionally specified
name and possibly distinct type."

The point is, a structure is an object just like any other object; there
is no special constraint on it of the type you describe.

The draft Standard goes on to describe what happens on entry to a function:

Section 3.7.1:

"On entry to the function the value of each argument expression
shall be converted to the type of its corresponding parameter, as if
by assignment to the parameter. Array expressions and function
designators as arguments are converted to pointers before the call."

Structures are neither array objects nor function objects, and thus may
be passed by value.

gcc -pedantic -Wall -c his.c.file.c -o /dev/nul

produces no warnings or errors for his code. However, Turbo C 2.0 seems
to have the problem he is describing:

Warning [...]: Structure passed by value...
Error [...]: Type mismatch in parameter 'a' in call to 'asdf'...

Changing the prototype to "const struct qwert a" fixes the error, but does
not remove the warning. The compiler is warning that it specifically *is*
an ANSI C compiler, and will pass structures by value unless told to do
otherwise with the & operator. UNIX compilers traditionally converted
such references to pointers, so if someone is using Turbo C to port
some UNIX code, this is a very useful warning.

Actually, I'm somewhat surprised that Turbo C didn't just throw out the
"const" in:

void asdf(const struct qwert a);

I wouldn't think "const" would mean much for a non-pointer parameter passed
by value.

Will

Doug Gwyn

unread,
Feb 24, 1990, 1:29:56 PM2/24/90
to
In article <90054.232...@psuvm.psu.edu> CMH...@psuvm.psu.edu (Charles Hannum) writes:
>The double is passed by value; so dereferencing it works fine. But the
>struct is passed by reference (as are *all* structures in C!). In reality,
>you need to pass a "struct qwert *" to the function. Normally, the compiler
>takes the reference automatically, but you are trying to do this in reverse.
>Thus, it does not work; you simply can't pass a structure by value.

You shouldn't answer questions when you don't know what you're talking
about. Structure arguments to functions are passed by value, not by
reference. The implementation may play funny games that amount to
building a private copy of the structure and passing a reference to
the private copy, but from the point of view of the programmer the
structure is passed by value and has exactly the properties one would
expect for the by-value mechanism.

The compiler was correct to complain about an argument that had as its
type "pointer to qualified type" being passed to a function expecting
a pointer to an unqualified type. That violates 3.3.16.1 (as referred
to in 3.3.2.2); and that is a logical constraint for the standard to
have imposed, because the function may try to store into the pointed-to
location but since the pointed-to storage is actually defined as having
the const attribute that would be a mistake.

Henry Spencer

unread,
Feb 24, 1990, 6:37:25 PM2/24/90
to
In article <12...@watserv1.waterloo.edu> sem...@watsci.UUCP (Robert Adsett) writes:
>...If I either add const to the prototype or remove it from
>the argument to junk it compiles without error. Is there some reason
>that 'const double *b' should be treated differently from 'const
>struct qwert *c'? ...

I'd diagnose this as a buggy or obsolete compiler. The semantics of
const in ANSI C were a moving target for quite some time.
--
"The N in NFS stands for Not, | Henry Spencer at U of Toronto Zoology
or Need, or perhaps Nightmare"| uunet!attcan!utzoo!henry he...@zoo.toronto.edu

Henry Spencer

unread,
Feb 24, 1990, 6:39:12 PM2/24/90
to
In article <90054.232...@psuvm.psu.edu> CMH...@psuvm.psu.edu (Charles Hannum) writes:
>... you simply can't pass a structure by value.

Passing (and returning) structures by value has been a feature of C for
over a decade.

D'Arcy J.M. Cain

unread,
Feb 24, 1990, 9:53:27 PM2/24/90
to
In article <90054.232...@psuvm.psu.edu> CMH...@psuvm.psu.edu (Charles Hannum) writes:
>
>The double is passed by value; so dereferencing it works fine. But the
>struct is passed by reference (as are *all* structures in C!). In reality,
>you need to pass a "struct qwert *" to the function. Normally, the compiler
>takes the reference automatically, but you are trying to do this in reverse.
>Thus, it does not work; you simply can't pass a structure by value.
>
Bzzzzzzt!!

That may be true for K&R1 but both K&R2 and ANSI both allow passing
structures by value. Granted this may not be something that you want
to do too often but it is permissible. Even K&R1 hinted that it would
one day be allowed.

You can even do something like the following:

struct qwert foo;
struct qwert bar(struct qwert x);

...

foo = bar(foo);

Of course sending the address would be more efficient in the above example.

--
D'Arcy J.M. Cain (darcy@druid) | Thank goodness we don't get all
D'Arcy Cain Consulting | the government we pay for.
West Hill, Ontario, Canada |
(416) 281-6094 |

Elliott Finley

unread,
Feb 25, 1990, 4:34:29 PM2/25/90
to
(Charles Hannum) writes:

The double is passed by value; so dereferencing it works fine.
But the struct is passed by reference (as are *all* structures in
C!). In reality, you need to pass a "struct qwert *" to the
function. Normally, the compiler takes the reference
automatically, but you are trying to do this in reverse. Thus,
it does not work; you simply can't pass a structure by value.

Here is an excerpt from K&R2, chapter 6, page 127
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
The main change made by the ANSI standard is to define structure
assignment--structures may be copied and assigned to, passed to
functions, and returned by functions. This has been supported by most
compilers for many years, but the properties are now precisely
defined. Automatic structures and arrays may now also be initialized.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Chapter 6.2 page 129

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Let us investigate structures by writing some functions to
manipulate points and rectangles. There are at least three possible
approaches: pass components separately, pass an entire structure, or
pass a pointer to it. Each has its good points and bad points.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

So you can clearly see that the statement made above "But the
struct is passed by reference (as are *all* structures in C!)" is not true!

Elliot

P.S. It is ALOT more efficient to pass a pointer to a structure.

Walter Murray

unread,
Feb 26, 1990, 1:17:33 PM2/26/90
to
Robert Adsett:

> #include <math.h>
> struct qwert { int a; double b;};
> void asdf( struct qwert a);
> const double a = 3.0;
> void junk( const double *b, const struct qwert *c)
> {
> (void)exp(a); /* Works */
> (void)exp(*b); /* Works */
> asdf( *c); /* Type mismatch ???? */
> }

> The compiler gives a type mismatch in argument error for the line
> indicated.

Doug Gwyn:

> The compiler was correct to complain about an argument that had as its
> type "pointer to qualified type" being passed to a function expecting
> a pointer to an unqualified type.

But in the posted example, the argument and parameter are structures,
not pointers. It seems to me that the code is legal.

Walter Murray
----------

Doug Gwyn

unread,
Feb 27, 1990, 2:09:54 PM2/27/90
to
In article <1257...@hpclwjm.HP.COM> wal...@hpclwjm.HP.COM (Walter Murray) writes:
>But in the posted example, the argument and parameter are structures,
>not pointers. It seems to me that the code is legal.

Thanks for posting the original example, which I had misremembered
as passing a pointer, not the actual struct. Of course you're right
that a qualified struct can be passed to a function expecting an
unqualified struct, because the argument is assignment-compatible
(meaning: 3.3.16.1 Constraints are met) with the parameter type,
once the qualifier is stripped as per 3.2.2.1, as footnote 48 in the
December 1988 draft reminds us. It's easy to see how an implementor
could miss that, by not taking literally the requirement that
argument passing be as if by simple assignment.

0 new messages