[not a] Bug in GCC [but I still think it should be!]

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well who'd have thought. While developing my "mad simulator" idea I hit a bug in 4.3.3 (WinAVR20100110) that is shown by this:

#include 

int main(void) {
	switch (PINA) { 
		case 1:
			uint8_t tmp;
			break;
	}
	while(1);
} 

which results in:

../test.c:6: error: a label can only be part of a statement and a declaration is not a statement

This works OK:

#include 

int main(void) {
	switch (PINA) { 
		case 1:
		{
			uint8_t tmp;
		}
		break;
	}
	while(1);
} 

and so does this:

#include 

int main(void) {
	switch (PINA) { 
		case 1:
			PORTB = PORTB;
			uint8_t tmp;
			break;
	}
	while(1);
}

It's a variable declaration immediately following a case label that it doesn't like.

I tried 4.5.1 from "AVR Toolchain" but got the same. However Google seems to suggest this might be fixed later - but that doesn't help those of us using WinAVR.

I guess the simple solution there is to use braces if you plan to declare local variables at the top of the case.

[thread title edited]

Last Edited: Wed. Nov 2, 2011 - 06:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I guess the simple solution there is to use braces if you plan to declare local variables at the top of the case.
Or perhaps making the label part of an empty statement? (untested)

   case 1: ;

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tested - yes that's another solution.

If someone has a 4.6 or a 4.7 I'd be interested to know if this is now fixed?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is not a bug - this is what the standard requires. However strange/funny/idiotic that might be.

Did I mention I hate C?

JW

PS. 6.8.1, just in case.

Last Edited: Wed. Nov 2, 2011 - 06:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have chapter and verse on that? I cannot believe this is the first time in my life I've tried to create a variable at the top of a case: without enclosing braces?!?

(then again I suppose it could be - on the whole I probably would have used braces it's just this recent exposure to C++ is polluting my thinking - so I now think I can create variables anywhere - not just at the top of a statement block)

EDIT:

Quote:
PS. 6.8.1, just in case.

thanks - noted. So it seems that by "statement" that excludes a variable declaration then?

Last Edited: Wed. Nov 2, 2011 - 06:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I came late with the PS. It's 6.8.1; the syntax is explicitly
case constant-expression : statement

As gcc aptly warned you, a declaration is not a statement.

This is a non-classical example of the labels-gotcha; the classical one is a goto-label at the end of a block.

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Our edits are over-lapping - I just made a comment about that above. So statement != declaration then? Ho hum - I'll edit the thread title then.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Think of it in terms of the portable PDP-11 macroassembler and a very simplistic compiler, which simply goes through the source lines and immediately spits out the translated result (the PDP-11 had a rather limited memory, remember).

Declarations are basically storage allocation, so if the compiler comes across

char a;

it translates it into

a: .db 1

(and flips a bit to remember that it is inside .data) and if it finds something which can be a statement, like

a++;

it spits out

load r5, a
inc r5
store r5, a

To place them to proper place, it would maintain a bit indicating whether it is inside declarations or inside statements; and if changes from one to other or vice versa, it spits out .data or .text accordingly.

C- labels (including the switch/case scheme), of course, translate directly into assembler labels

By now you already see why there is need for a statement after the label: otherwise the label would end up in the incorrect (data) section.

Enjoy! :-P

Jan

PS. And if you don't like it, go for some real programming language ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IIRC there is a move afoot to change the standard to make switch cases into separate blocks.
Whether that would legalize Clawson's syntax would depend on where the standard-makers put the implicit braces.
It would definitely break some currently legal syntax.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
IIRC there is a move afoot to change the standard to make switch cases into separate blocks.
Whether that would legalize Clawson's syntax would depend on where the standard-makers put the implicit braces.
It would definitely break some currently legal syntax.
Source?
Actually I don't believe that, because it would break existing code. And changes to the standard are normally made without breaking existing code. There are really silly things still part of the language (like implicit function declarations) just because of that one reason: not to break existing code.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
skeeve wrote:
IIRC there is a move afoot to change the standard to make switch cases into separate blocks.
Whether that would legalize Clawson's syntax would depend on where the standard-makers put the implicit braces.
It would definitely break some currently legal syntax.
Source?
Were I able to give you a source, I wouldn't have needed the IIRC.
Quote:
Actually I don't believe that, because it would break existing code. And changes to the standard are normally made without breaking existing code.
Which is why the move should fail and probably will fail.
Quote:
There are really silly things still part of the language (like implicit function declarations) just because of that one reason: not to break existing code.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Think of it in terms of the portable PDP-11 macroassembler
> and a very simplistic compiler

Which is utter nonsense in Cliff's case, as it's only C99 which added
the ability to intersperse declarations/definitions and statements in
random order (something that has apparently been inspired by C++,
which in turn badly needed the feature since a definition triggers a
constructor there). In C89, let alone your ancient K&R C,
declarations/definitions were only allowed right after an opening
brace anyway, which would have avoided the issue straight from the
beginning.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dl8dtl wrote:
> Think of it in terms of the portable PDP-11 macroassembler
> and a very simplistic compiler

Which is utter nonsense in Cliff's case, as it's only C99 which added
the ability to intersperse declarations/definitions and statements in
random order


Oh, the reason for "label:statement" rule is sure not C99 specific, and related to simplicity of the compiler. You can't write labels outside blocks and can't write them before declarations at the beginning of the block in K&R either - and the reason is the very same, the labels would go into the incorrect section.

Once the rule was established for the reason described above, the compilers had to obey it even if it lost its original raison d'etre. And C99 did not change on it either. They could, but they did not, see the current wording. The compiler also could relax the rule, as a convenience to the programmer, at the cost of non-compliance.

And note, that it's only the strict application of "label:statement" rule which results in the "canonical" goto label gotcha I mentioned above (no labels at the end of block), there's no rationale for it even in the simplistic compiler context.

But if you insist on that this is "utter nonsense", I would really like to hear your non-nonsense explanation, why is Cliff's construction considered an error.

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which language allows labelling non-statements?

I think the mere problem is the way the case statement iself
has been designed. But that's an old story, see Duff's device.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dl8dtl wrote:
Which language allows labelling non-statements?

BASIC, for example.

Pascal, while requires the label:statement syntax, in its definition of statements includes an empty statement, which is nothing (that's the result terminator/separator use of ; in C/Pascal). That alleviates the problem of the label at the end of block or compound statement (i.e. just before "end").

Btw. how did your question explain the cause of Cliff's problem?

dl8dtl wrote:
I think the mere problem is the way the case statement iself has been designed.
That's a different, more extensive, albeit related, problem.

Jan