Pages: 1 [2] 3   Go Down
Author Topic: name lookup of 'i' changed for new ISO 'for' scoping  (Read 4934 times)
0 Members and 1 Guest are viewing this topic.
United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.

Why?  That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list:

Code:
for(ptr=head; ptr->next; ptr=ptr->next);
ptr->next = newelement;

Yes, it's valid C++, but convention is that if you really want to write a loop with an empty body, you indicate that it is intentional, either by using { }, or by putting a newline or a comment between the ) and the ; .
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.

Why?  That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list:

Code:
for(ptr=head; ptr->next; ptr=ptr->next);
ptr->next = newelement;

Yes, it's valid C++, but convention is that if you really want to write a loop with an empty body, you indicate that it is intentional, either by using { }, or by putting a newline or a comment between the ) and the ; .

Yes, but strip the newlines and the comments, which is generally what the compiler does, and how can it tell the difference?  It can't - so no warnings.  Neither I, nor the compiler, care what different people do as "convention" - you can't have a warning for something that is perfectly valid, just not correct.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

you can't have a warning for something that is perfectly valid, just not correct.

That's the entire point of a warning rather than an error.  this code is valid:
Code:
  if (n = 8) {
   
  }

In fact, that is even used:
Code:
int ret;
const char* s = "Hello there", t = "Hello There";
if (ret = strcmp(s, t)) {
  // strings do not match
}
else {
  // strings do match
}
so the compiler's warning says "put parentheses around it to show me you know it's weird."

Something that could be correct but probably isn't shouldn't get a warning unless there's a way of expressing the same thing without getting the warning. So it could be an error for if(statement); {/*...*/} but it could be suppressed by if(statement) { } {/*...*/
Logged

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

you can't have a warning for something that is perfectly valid, just not correct.

That's the entire point of a warning rather than an error.  this code is valid:
Code:
 if (n = 8) {
    
  }

In fact, that is even used:
Code:
int ret;
const char* s = "Hello there", t = "Hello There";
if (ret = strcmp(s, t)) {
  // strings do not match
}
else {
  // strings do match
}
so the compiler's warning says "put parentheses around it to show me you know it's weird."

Something that could be correct but probably isn't shouldn't get a warning unless there's a way of expressing the same thing without getting the warning. So it could be an error for if(statement); {/*...*/} but it could be suppressed by if(statement) { } {/*...*/

So how would you suggest suppressing a warning for

Code:
for(ptr=head; ptr->next; ptr++);
?

By the way, the precompiler strips all comments, so putting comments in something is a futile exercise.  An empty block gets reduced to an end of statement (smiley-wink.

Warnings are there for things that are programatically iffy.

You can't have a warning for something that is valid, just because in that one specific situation the programmer used it wrong.

You can't have a warning because the maths you used in a formula is wrong, but you can have a warning if the order of precedence, or the order of assignment, etc, is not clear.

You can't warn the user that they have written the wrong program.
« Last Edit: November 03, 2012, 08:12:06 pm by majenko » Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

but it could be suppressed by if(statement) { } {/*...*/

So how would you suggest suppressing a warning for

Code:
for(ptr=head; ptr->next; ptr++);
?

umm.. did you read the last sentence of the post you quoted?
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So how would you suggest suppressing a warning for

Code:
for(ptr=head; ptr->next; ptr++);
?

By the way, the precompiler strips all comments, so putting comments in something is a futile exercise.

Only if the preprocessor (or precompiler as you call it) is a separate program from the main compiler, which is rarely the case these days.

 An empty block gets reduced to an end of statement (;).

It may be treated in the same way as end-of-statement in some contexts, but the compiler knows the difference, so it is easy for the compiler writter to generate a warning in one case but not in the other.

You can't have a warning for something that is valid, just because in that one specific situation the programmer used it wrong.

Rubbish. There are very many things that are valid in C++ but symptomatic of possible or likely errors, and all good C++ compilers can warn about many of them. You can choose to run the compiler at its minimum warning level and see none of these warnings, or the maximum warning level and see all of them, or somewhere in between. See http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html for the warning options supported by the gcc compiler used by the Arduino IDE. In particular, note the following:

Quote
-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

An if, while, for, etc does not "own" the { and }.  It merely expects a valid statement.

; is a valid statement.

moveServoToPosition(90); is a valid statement.

{ moveServoToPosition(90); } is a valid statement.

{ } is a valid statement.

The { and } merely convert the containing statements into a single compound statement as seen by the parent layer (the if, while, whatever).

While I agree that an if statement with no body (if(x==3)smiley-wink is syntactically correct, it is pointless, and yes a warning "If without body" could be generated.   However, we're not arguing about ifs here - if was introduced about half way through the discussion by WizenedEE.

The code

Code:
for(ptr=head; ptr->next; ptr++);

and the code
Code:
for (int i = 1500; i >= 1000; i --);

are both perfectly syntactically correct, and in some circumstances are programatically correct as well - i.e., they are exactly what the programmer intended.

There is no way for a compiler to know what a programmer intends.

If you want to start forcing a { } to indicate an intentional empty body, then two things are happening:

1. You are forcing a coding style on someone.  This is not something that C does.  Python imposes coding styles.  COBOL imposes coding styles.  Upper management impose coding styles.  C doesn't, it never has, and it never will.

2.  It will break the C specification, which states that the above code is valid.

And then, will you warn about:

Code:
for(x=0; x<10; x++)
  doSomething(x);

just because the doSomething(x) isn't inside a { and } ?

Quote
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.

None of the above three chunks of code are in any way questionable, vague, or otherwise suspect.  They are perfectly valid.

Modifying them to "prevent the warning" involves things like adding extra brackets around assignments, etc - not changing the whole structure of the C language!
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The code

Code:
for(ptr=head; ptr->next; ptr++);

and the code
Code:
for (int i = 1500; i >= 1000; i --);

are both perfectly syntactically correct, and in some circumstances are programatically correct as well - i.e., they are exactly what the programmer intended.

Whilst I agree that those examples are not quite in the same category as "if (x = 8)", I think the fact that the OP made the mistake of putting in that semicolon and had to ask for help to find it demonstrates the usefulness of a compiler warning for this construct.

If you want to start forcing a { } to indicate an intentional empty body, then two things are happening:

1. You are forcing a coding style on someone.  This is not something that C does.  Python imposes coding styles.  COBOL imposes coding styles.  Upper management impose coding styles.  C doesn't, it never has, and it never will.

Anyone who writes commercial C code without a coding style and a tool that enforces that style (even if that tool is just the compiler with extra warnings enabled) is IMO stupid and irresponsible. But Arduino is intended for hobbyists and novices, so the situation here is less clear cut. I would like the Arduino IDE to provide a choice of warning levels, or some way of passing additional flags to gcc.

2.  It will break the C specification, which states that the above code is valid.

Warning about questionable code does not break the C specification. Refusing to compile it would.

None of the above three chunks of code are in any way questionable, vague, or otherwise suspect.  They are perfectly valid.

We'll have to agree to differ about that.

Modifying them to "prevent the warning" involves things like adding extra brackets around assignments, etc - not changing the whole structure of the C language!

Requiring the programmer to put the semicolon on a different line from the end of the loop header (in order to make his intention clear and suppress the warning) does not change the structure of the C language either. [Although all C coding standards for safety-critical software I have seen do make { } compulsory in the bodies of all loops and if-statements, in order to reduce the incidence of errors.]

BTW I believe gcc does warn about for-loops of this form if you use the -Wextra or -Wempty-body compiler options. It's not documented on the page I linked to, but I found a note that gcc extends that warning to include for-loops from gcc 4.3.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Whilst I agree that those examples are not quite in the same category as "if (x = smiley-cool", I think the fact that the OP made the mistake of putting in that semicolon and had to ask for help to find it demonstrates the usefulness of a compiler warning for this construct.

No, it highlights the fact that, given the target market for the Arduino, the C language was a very poor choice.  It is a very complex language, and easy to make mistakes if you don't know what you're doing - and in the land of the Arduino, 9 times out of 10, the "programmers" don't know what they are doing.  This is often the first time they have written any code in their lives.

Quote
Anyone who writes commercial C code without a coding style and a tool that enforces that style (even if that tool is just the compiler with extra warnings enabled) is IMO stupid and irresponsible. But Arduino is intended for hobbyists and novices, so the situation here is less clear cut. I would like the Arduino IDE to provide a choice of warning levels, or some way of passing additional flags to gcc.

The coding style starts with the user.  If they don't know what they're doing, no amount of forced coding styles (which I abhor - coding styles are *personal*), and warnings (which on the Arduino are pointless, because a) the line numbers are wrong, and b) people don't read them, they just post snippets of them on here and ask what is wrong), will make them better programmers.

I could sit here all day and go on about things that could be improved with the Arduino so called "IDE", and yes, the ability to set compiler options (warnings, and such) is pretty high on my list.  But it does come below having an IDE that is actually usable for anything more than writing short little test snippets of code.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The coding style starts with the user.  If they don't know what they're doing, no amount of forced coding styles ... and warnings (which on the Arduino are pointless, because a) the line numbers are wrong, and b) people don't read them, they just post snippets of them on here and ask what is wrong), will make them better programmers.

But extra warnings help people who mostly do know what they are doing avoid making silly mistakes. I once had to convert 4 million lines of C++ code, written by programmers who were extremely competent, to be compatible with a new compiler and its associated libraries. At the same time, I increased the compiler warning level to near maximum. The new warnings revealed more than 200 bugs in the code. This was in code that had been tested and released.

If the line number in Arduino messages are wrong sometimes, that should be fixed. I find the error message line numbers are mostly OK.

(which I abhor - coding styles are *personal*)

I guess you are either a hobbyist or a one-developer company, because that attitude is not workable in a multi-developer team. In safety-critical work, companies mostly pick one of a few standard coding rule sets such as MISRA-C, MISRA-C++ and JSF C++.

I've not commented on your other points because I agree with them at least in part.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The coding style starts with the user.  If they don't know what they're doing, no amount of forced coding styles ... and warnings (which on the Arduino are pointless, because a) the line numbers are wrong, and b) people don't read them, they just post snippets of them on here and ask what is wrong), will make them better programmers.

But extra warnings help people who mostly do know what they are doing avoid making silly mistakes. I once had to convert 4 million lines of C++ code, written by programmers who were extremely competent, to be compatible with a new compiler and its associated libraries. At the same time, I increased the compiler warning level to near maximum. The new warnings revealed more than 200 bugs in the code. This was in code that had been tested and released.
That I agree with.  I always code with -Wall turned on.

Quote
If the line number in Arduino messages are wrong sometimes, that should be fixed. I find the error message line numbers are mostly OK.

(which I abhor - coding styles are *personal*)

I guess you are either a hobbyist or a one-developer company, because that attitude is not workable in a multi-developer team. In safety-critical work, companies mostly pick one of a few standard coding rule sets such as MISRA-C, MISRA-C++ and JSF C++.

One developer company at the moment, but I have worked in large development teams.  I find my personal coding style fits in pretty well with others - and I am willing to change my coding style to fit in with management's desires - but at the end of the day I believe that the coding style that is most comfortable for an experienced programmer to work with is the one least prone to them making mistakes in.

"Standard" coding styles are only really there so that other developers in the team can understand easily what you have written.  That and comments (something else I am not good at smiley-wink ).

What gets most confusing though is when you are part of a project team with multiple programming languages involved, and you have different programming styles imposed upon you for each language - either by management (which I find is often the case of you conforming to your boss's style of programming, and not to any particular "standard" - at least in the industries I have worked in), or the differences in language structures.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, and I often also use -Werror, so I can't compile with any warnings smiley-wink
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How often does this happen?
Code:
for(ptr=head; ptr->next; ptr++);
{
  printf("Hello!");
}
It makes sense to warn about that. If the programmer intended for it to be for->semicolon->blockofcode, they could do this:
Code:
for(ptr=head; ptr->next; ptr++) {}
{
  printf("Hello!");
}

However, obviously no warning should be shown for this:
Code:
for(ptr=head; ptr->next; ptr++);
printf("Hello!");
or this
Code:
for(ptr=head; ptr->next; ptr++) printf("Hello!");
and only maybe this
Code:
for(ptr=head; ptr->next; ptr++) printf("hi");
{
  printf("Hello!");
}
Logged

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A warning for a code block with no parent if/for/while etc is valid, yes.  You can't give warnings for bad indentation, unless you want to program in COBOL.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A warning for a code block with no parent if/for/while etc is valid, yes.

What? No way. There are plenty of valid reasons to use a block with no statement, ranging from controling when things are destroyed (especially important for the ATOMIC_BLOCK things) to being able to declare new variables in a switch statement.
Logged

Pages: 1 [2] 3   Go Up
Jump to: