Questions on incomplete structure type

L

Luca Forlizzi

Hello,

while studying incomplete types, I wrote the below example
containing, I think,
several undef. behaviors. Trying it with two different compilers I
find out
that expressions that, in my opinion, are all undef. b. for the same
reason,
produce non uniform translations (I used -std=c99 -pedantic-errors -
Wall for gcc).

I have the following questions:
1)Am I right that all the 8 expressions casted to void are undef.b.
per 6.3.2.1 p.2
2) gcc prints "error: dereferencing pointer to incomplete type"
while trying
to translate
(void) *ps;
Does the standard forbids to dereference a pointer to an
incomplete type?
I was unable to find such a prohibition, moreover gcc silently
accepts
dereferencing a pointer to an incomplete array type. In my
opinion the
error message is misleading regading the nature of the error.

/*------------------ EXAMPLE --------------------*/

/* declaration of an external variabile of incomplete type; later
type is completed and variable defined */
struct S external_s;

/* tentative definition of a variable with incomplete type;
later type is completed and the tentative def becomes a definition
(the variable is implicitly initialized to {0}) */
struct S tentative_s;

int main(void) {

/* pointers to the incomplete structure type */
struct S *ps, *qs;

/* declaration of functions returning an incomplete structure type */
struct S hht(void);
struct S hhe(void);


ps = &tentative_s;
qs = &external_s;

/* all following statements are (discarded) computation of an
expression
having an incomplete structure type.
Are they all undef.b. per 6.3.2.1 p.2 ?
*/

/* gcc emits diagnostics, vbcc silently accepts them */
(void) hht();
(void) hhe();

/* both gcc and vbcc emit diagnostics */
(void) *ps;
(void) *qs;

/* gcc silently accepts them, vbcc emits diagnostics */
(void) * &tentative_s;
(void) * &external_s;

/* both gcc and vbcc silently accept them */
(void) tentative_s;
(void) external_s;

return 0;
}

/* declaration that completes the structure type and defines
external_s */
struct S { float a; int b, c; } external_s = { 1.1, 2, 3, };

/* functions returning the here-complete structure type */
struct S hht(void) {

return tentative_s;
}

struct S hhe(void) {

return external_s;
}
 
B

Barry Schwarz

Hello,

while studying incomplete types, I wrote the below example
containing, I think,
several undef. behaviors. Trying it with two different compilers I
find out
that expressions that, in my opinion, are all undef. b. for the same
reason,
produce non uniform translations (I used -std=c99 -pedantic-errors -
Wall for gcc).

I have the following questions:
1)Am I right that all the 8 expressions casted to void are undef.b.
per 6.3.2.1 p.2

There is a slight difference between constraint violations and
undefined behavior. The former leads to the latter but there are
other causes of undefined behavior.
2) gcc prints "error: dereferencing pointer to incomplete type"
while trying
to translate
(void) *ps;
Does the standard forbids to dereference a pointer to an
incomplete type?

There is footnote 36 which says an incomplete type is not an object.
6.5.3.2-4 defines the result of * operator only if it points to a
function or to an object. Your code seems to be a constraint
violation.
I was unable to find such a prohibition, moreover gcc silently
accepts
dereferencing a pointer to an incomplete array type. In my
opinion the

Show the code. Even if gcc is wrong, it doesn't change the language
spec.
error message is misleading regading the nature of the error.

Based on 6.5.3.2-4, it seems almost letter perfect, if a little terse.
/*------------------ EXAMPLE --------------------*/

/* declaration of an external variabile of incomplete type; later
type is completed and variable defined */
struct S external_s;

/* tentative definition of a variable with incomplete type;
later type is completed and the tentative def becomes a definition
(the variable is implicitly initialized to {0}) */
struct S tentative_s;

int main(void) {

/* pointers to the incomplete structure type */
struct S *ps, *qs;

/* declaration of functions returning an incomplete structure type */
struct S hht(void);
struct S hhe(void);

6.9.1-3 says the return type must be void or an object type. Footnote
36 says incomplete types are not objects. This is a constraint
violation.
 
L

Luca Forlizzi

Hi Barry

There is a slight difference between constraint violations and
undefined behavior.  The former leads to the latter but there are
other causes of undefined behavior.

yes, but I don't understand how this answer my question.
There is footnote 36 which says an incomplete type is not an object.
6.5.3.2-4 defines the result of * operator only if it points to a
function or to an object.  Your code seems to be a constraint
violation.

mmmhhh... footnote 36 says that an object *type* is not an incomplete
type.
In my code * is applied to pointers which actually refer to objects.
It's only that the objects have an incomplete type

Show the code.  Even if gcc is wrong, it doesn't change the language
spec.

extern int x, a[];

int main(void) { x=*a; return x; }

int a[] = { 0, 2}; /* completes the type */

isn't this strictly conforming?
 
L

Luca Forlizzi

oopps! :-}
my answer to your second answer is obviously wrong, I am in a
hurry. :-}
But I think it is allowed to dereference a pointer to an incomplete
array type. The following should be ok (I hope):

int (*p)[];
int a[5], b[4];

int main(void) { p = &a; return (*p)[2]; }

Show the code.  Even if gcc is wrong, it doesn't change the language
spec.

extern int x, a[];

int main(void) { x=*a; return x; }

int a[] = { 0, 2}; /* completes the type */

isn't this strictly conforming?
 
M

Marcin Grzegorczyk

Barry said:
On Fri, 5 Nov 2010 08:41:24 -0700 (PDT), Luca Forlizzi


There is footnote 36 which says an incomplete type is not an object.

Note that this has changed in C1X. It has been agreed that completeness
is a scoped property of an object type, so instead of "object type" vs.
"incomplete type" there is now "complete object type" vs. "incomplete
object type". The former footnote 36 is gone; instead, there is a new
sentence (not a footnote): "The element type shall be complete whenever
the array type is specified".
6.5.3.2-4 defines the result of * operator only if it points to a
function or to an object. Your code seems to be a constraint
violation.

6.5.3.2p4 is in the Semantics section, not Constraints.

[...]
6.9.1-3 says the return type must be void or an object type. Footnote
36 says incomplete types are not objects. This is a constraint
violation.

6.9.1 is about definitions, not declarations.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top