User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 6:17 am

Paeryn wrote:The -Wmissing-prototypes and -Wmissing-declarations warnings aren't meant as warnings against bad code, they are more for checking that external functions have declarations in header files. If you decided to rename a function in the source code of a library but forgot to rename it in the header file then the compiler would flag it up as the function would no longer have a matching declaration in the header. Just compiling the library wouldn't necessarily pick up on that if the function is never called from within the library itself.

missing-prototypes is for catching when you declare a function without giving a prototype. This will catch cases where you don't provide the function parameters in the header (which missing-declarations won't).
I understand what they are for, I read the manual page :-) The problem is that my (may be slightly out of date) code style falls foul of these warnings for no good reason. They produce warnings on perfectly good code which makes them next to useless for me. Who ever designed them seems to have decided to unilaterally add constraints to their definition of valid C code and I'm not going to waste my time checking and fixing my code just to placate some broken (*) warnings.

PeterO.

(*) Broken in my case , but I appreciate could be useful for others.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
Paeryn
Posts: 2834
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 9:19 am

PeterO wrote:I understand what they are for, I read the manual page :-) The problem is that my (may be slightly out of date) code style falls foul of these warnings for no good reason. They produce warnings on perfectly good code which makes them next to useless for me. Who ever designed them seems to have decided to unilaterally add constraints to their definition of valid C code and I'm not going to waste my time checking and fixing my code just to placate some broken (*) warnings.

PeterO.

(*) Broken in my case , but I appreciate could be useful for others.
Your code is not likely to be the intended use case for these warnings so they are inappropriate to use. You would use them iff every function in the source file should have a prototype/declaration in a given header(s) and you want to make sure that they do without having to link the code against example code. That's why the warnings don't consider a function definition to be its own prototype/declarartion, they are for when you know that every function should have one and you want to check that you haven't missed any.

Basically for most people those warnings should never be set, even for people who need them they should only be set on the specific files that provide only external functions (lest they want all the noise from false positives of internal functions).
She who travels light — forgot something.

jahboater
Posts: 5197
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 9:31 am

An expensive static checker that has a free demo.
I've used this quite a bit many years ago, I don't know how up to date it is.

http://www.gimpel.com/html/index.htm

see "Interactive demo"
go to the "do it you self example" bits and you can paste in large chunks of your own code to be checked.

http://www.gimpel-online.com/OnlineTesting.html

Expect a few false positives!

jahboater
Posts: 5197
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 9:35 am

Paeryn wrote:Basically for most people those warnings should never be set, even for people who need them they should only be set on the specific files that provide only external functions (lest they want all the noise from false positives of internal functions).
For those who want a basic check that all functions are either declared before use or have a prototype, what do you suggest?

mikerr
Posts: 2814
Joined: Thu Jan 12, 2012 12:46 pm
Location: UK
Contact: Website

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 9:38 am

DougieLawson wrote: It would be useful if any folks who are providing code for beginners on this forum would compile their stuff with at least some of those flags. There's too much with invalid main() functions (returns void, does return int or simply uses return;) which isn't good for the folks who are new to C programming. If it's some junk example for something I'm trying for myself (before including it in a larger project) it probably doesn't matter. As soon as you publish it for other folks it should cleanly pass most of those compiler tests.
Yes, but if you only wait to publish working code until sometime after you've cleaned it up
then you may never get around to sharing that code ! Everyone's loss..

https://en.wikipedia.org/wiki/Release_e ... ease_often
Android app - Raspi Card Imager - download and image SD cards - No PC required !

User avatar
Paeryn
Posts: 2834
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 9:55 am

jahboater wrote:
Paeryn wrote:Basically for most people those warnings should never be set, even for people who need them they should only be set on the specific files that provide only external functions (lest they want all the noise from false positives of internal functions).
For those who want a basic check that all functions are either declared before use or have a prototype, what do you suggest?
If you want to make sure all functions have a previous declaration or prototype then the warnings are fine as that is what they are for, but as PeterO says, perfectly valid c (where you define before use without explicit declaration) will get you warnings. These are tools for spotting potential errors in specific cases where C cannot normally check (like making sure a function is externally visible).
She who travels light — forgot something.

User avatar
DougieLawson
Posts: 37591
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 10:01 am

mikerr wrote: Yes, but if you only wait to publish working code until sometime after you've cleaned it up
then you may never get around to sharing that code ! Everyone's loss..

https://en.wikipedia.org/wiki/Release_e ... ease_often
That may be true when everyone is a professional programmer, but we're discussing posting code samples/examples that will be used by the folks just starting out learning C/C++. Get the bad habits knocked out early and RERO becomes a natural progression from that. Ingrain some bad habits at the beginning and you get lousy code forever (and I've seen some lousy code (especially from off-shore application wonks) in my thirty five years working in systems programming).
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

jahboater
Posts: 5197
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Sat Apr 08, 2017 10:04 am

mikerr wrote:
DougieLawson wrote: As soon as you publish it for other folks it should cleanly pass most of those compiler tests.
Yes, but if you only wait to publish working code until sometime after you've cleaned it up
then you may never get around to sharing that code !
Most code published here is very small and should only take a minute or so to cleanup. Some people have clearly not even compiled the program first! Others have not really examined their own code at all (there was a recent thread where a program failed because the function that did all the work was not even being called - in trivially small program).

Code that is published as part of a tutorial should be correct, squeaky clean, standards compliant, and portable.

Requests for help have less onerous requirements, but it would avoid wasting peoples time if the basic static compiler checks were done first.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sun Apr 09, 2017 5:42 pm

I fully agree, for a quick and dirty code solution about a rough source code idea it should at least compile without any issues, some warnings may be acceptable (-Wall)
Instead, for a tutorial to beginners, either code is expected to compile super clean, even without any a warning (-Wall). Anything else would be extremely confusing to beginners and so would be absolutely inacceptable.

The gcc setup has to be the same as for the current Raspbian Jessie release, latest apt update + upgrade. Unfortunately gcc (g++) is still no 6.x (C++11) on the current Jessie, but that has to be considered as well for a tutorial to C/C++ targeting Raspberry Pi users.

User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sun Apr 09, 2017 5:59 pm

Lets not forget that this is not really a C specific issue, but it seems that certain people presenting themselves at "C tutors" are in fact not able to meet the standards we would expect for ANY tutorials in ANY language. It just seems that the problem has arisen first with poor quality C code.

PeterO

EDIT: OPSE missing "not" :-)
Last edited by PeterO on Sun Apr 09, 2017 6:54 pm, edited 1 time in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

jahboater
Posts: 5197
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Sun Apr 09, 2017 6:45 pm

1dot0 wrote:The gcc setup has to be the same as for the current Raspbian Jessie release, latest apt update + upgrade. Unfortunately gcc (g++) is still no 6.x (C++11) on the current Jessie, but that has to be considered as well for a tutorial to C/C++ targeting Raspberry Pi users.
Definately.

gcc 4.9 (the current compiler on Raspian) does actually support C++11 and C11, its just not the default. So it is perhaps reasonable to use C11 language features in examples, just tell people to add -std=c11.

User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 11:53 am

So here we are a few weeks down the line, and I'm finally getting the hang of writing code that doesn't fall foul of jahboater's long list of warning flags. I am finding it necessary to use lots of casts betwen ints and unsigned ints because of inconsistencies between libraries (e.g. some use signed, some use unsigned for things like widget sizes).

I'm currently up to 7500 lines with no warnings :-)

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:06 pm

tbh, I can't get rid of the tons of warnings (gpp -Wall) about " depricated conversion from string constant to 'char*' [-Wwrite -strings] "

User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:25 pm

1dot0 wrote:tbh, I can't get rid of the tons of warnings (gpp -Wall) about " depricated conversion from string constant to 'char*' [-Wwrite -strings] "
Show us some sample code that gives this warning. Google tells me it's probably missing "const" in front of "char *" .
PeterO

PS: Like Paeryn said !
Last edited by PeterO on Sat Apr 22, 2017 12:30 pm, edited 3 times in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
Paeryn
Posts: 2834
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:28 pm

1dot0 wrote:tbh, I can't get rid of the tons of warnings (gpp -Wall) about " depricated conversion from string constant to 'char*' [-Wwrite -strings] "
If you haven't been using const char * where you know the string won't be altered then you'll get tons of those warnings. That's because with -Wwrite-strings a C string literal (e.g. "hello") actually has the type const char * and a lot of people don't bother to declare functions as taking const char * when they actually do, they tend to just declare them as char *. The compiler option -Wwrite-strings is warning you that your code could potentially try writing to a string constant.

<Edit> In C++ string literals are always const char[length]. Compiling plain C gives a different warning about discarding the const qualifier.
She who travels light — forgot something.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:46 pm

PeterO wrote:
1dot0 wrote:tbh, I can't get rid of the tons of warnings (gpp -Wall) about " depricated conversion from string constant to 'char*' [-Wwrite -strings] "
Show us some sample code that gives this warning. Google tells me it's probably missing "const" in front of "char *" .
PeterO

PS: Like Paeryn said !
e.g., for the line
putenv ("WIRINGPI GPIOMEM=1");
(got that from one of Gordon's sources)

OTOH, this one is now clear:
char * kbdin = "/dev/input/event0";
char * i2c-1 = "/dev/i2c-1";

User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:51 pm

I guess you are one of those C++ programmers then... In C your code gets these warnings.

Code: Select all

/home/petero/803-GTK3/Editor.c: In function ‘EditorInit’:
/home/petero/803-GTK3/Editor.c:986:16: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
 char * kbdin = "/dev/input/event0";
                ^
/home/petero/803-GTK3/Editor.c:987:1: warning: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [enabled by default]
 putenv ("WIRINGPI GPIOMEM=1");
 ^
In file included from /usr/include/freetype2/config/ftstdlib.h:119:0,
                 from /usr/include/freetype2/config/ftconfig.h:43,
                 from /usr/include/freetype2/freetype.h:33,
                 from /home/petero/803-GTK3/Editor.c:807:
/usr/include/stdlib.h:578:12: note: expected ‘char *’ but argument is of type ‘const char *’
 extern int putenv (char *__string) __THROW __nonnull ((1));
            ^
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 12:54 pm

I am actually no C++ programmer, I just need gpp because some of my included libs use C++ code to instance a class.

jahboater
Posts: 5197
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:18 pm

1dot0 wrote: e.g., for the line
putenv ("WIRINGPI GPIOMEM=1");
(got that from one of Gordon's sources)
Thats interesting

Code: Select all

       #include <stdlib.h>

       int putenv(char *string);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       putenv(): _SVID_SOURCE || _XOPEN_SOURCE
but read the notes, as you can see at the end, the const was deliberately removed.

Code: Select all

NOTES
       The putenv() function is not required to be reentrant, and the one in glibc  2.0  is  not,
       but the glibc 2.1 version is.

       Since  version 2.1.2, the glibc implementation conforms to SUSv2: the pointer string given
       to putenv() is used.  In particular, this string becomes part of the environment; changing
       it  later  will change the environment.  (Thus, it is an error is to call putenv() with an
       automatic variable as the argument, then return from the calling function while string  is
       still  part  of  the environment.)  However, glibc versions 2.0 to 2.1.1 differ: a copy of
       the string is used.  On the one hand this causes a memory leak, and on the other  hand  it
       violates SUSv2.

       The 4.4BSD version, like glibc 2.0, uses a copy.

       SUSv2 removes the const from the prototype, and so does glibc 2.1.3.

This means you might need to make a copy of the string into a malloc'ed buffer first to be safe.

User avatar
DougieLawson
Posts: 37591
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:19 pm

1dot0 wrote:
e.g., for the line
putenv ("WIRINGPI GPIOMEM=1");
(got that from one of Gordon's sources)
With the latest version of WiringPi that has been deprecated. It now assumes that envvar is always set.
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

User avatar
Paeryn
Posts: 2834
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:20 pm

1dot0 wrote:e.g., for the line
putenv ("WIRINGPI GPIOMEM=1");
(got that from one of Gordon's sources)
You should be really careful using putenv as it puts the actual string into the environment, not a copy of it (which is why the string isn't declared const). You should really use setenv over putenv as that copies the strings. Although as long as you are using a string constant there shouldn't be much of a problem.
She who travels light — forgot something.

User avatar
PeterO
Posts: 5623
Joined: Sun Jul 22, 2012 4:14 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:26 pm

The NOTES section on the putenv man page is pretty bizarre !
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:33 pm

Paeryn wrote:
1dot0 wrote:e.g., for the line
putenv ("WIRINGPI GPIOMEM=1");
(got that from one of Gordon's sources)
You should be really careful using putenv as it puts the actual string into the environment, not a copy of it (which is why the string isn't declared const). You should really use setenv over putenv as that copies the strings. Although as long as you are using a string constant there shouldn't be much of a problem.
I took this line originally from Gordon Henderson... :?

how would the setenv line look like?

User avatar
Paeryn
Posts: 2834
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 1:46 pm

PeterO wrote:The NOTES section on the putenv man page is pretty bizarre !
PeterO
They tried altering how putenv worked, it caused problems, they reverted it. I never liked putenv due to it's problems.

1dot0:

Code: Select all

int setenv(const char *var_name, const char *var_value, int overwrite);
where var_name is the name of the variable to create, var_value is the value it will have, and overwrite says what to do if the variable already exists. If overwrite is 0 and the variable already exists it's value won't be changed. It returns 0 if successful.
She who travels light — forgot something.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 2:01 pm

Paeryn wrote: 1dot0:

Code: Select all

int setenv(const char *var_name, const char *var_value, int overwrite);
where var_name is the name of the variable to create, var_value is the value it will have, and overwrite says what to do if the variable already exists. If overwrite is 0 and the variable already exists it's value won't be changed. It returns 0 if successful.
...would mean what?

setenv("WIRINGPI GPIOMEM",1, true); :?:

Return to “C/C++”