User avatar
rpdom
Posts: 16776
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 2:08 pm

Code: Select all

setenv("WIRINGPI_GPIOMEM", "1", true);
Note the underscore, and the "1" being a char string.

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

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 2:12 pm

1dot0 wrote:
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); :?:
Not quite, the value has to be a string not an integer.
Is there really a space in the variable name? Just looked, no there isn't it's an underscore

Code: Select all

setenv("WIRINGPI_GPIOMEM", "1", true);
She who travels light — forgot something.

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

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 2:27 pm

And I think it's all moot anyway since /dev/gpiomem is checked for automatically now (or am I mixing things up ?) .

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

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

Re: Writing clean code isn't hard!

Sat Apr 22, 2017 2:36 pm

I think so (that it checks it, not that you are mixing it up). Especially as if 1dot0 was using a space in the middle of the variable name to putenv then it would have had no effect on wiringpi.
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 4:48 pm

@all: (edit)
thanks a lot, "WIRINGPI_GPIOMEM" was just a typo, but now I see what instead was wrong 8-)

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 8:15 am

OK, back to the original topic. Compiling some legacy code with all those extra warnings enabled is still keeping me entertained :lol: My latest battle is with "+=":

Is it possible to use "+=" operator with uint8_t on both sides without getting a type conversion warning ?

For example....

Code: Select all

#include <stdint.h>

int main(__attribute__((unused)) int argc,__attribute__((unused)) char **argv)
{
    uint8_t ch,a;

    ch = 0x10;
    a = 0x20;

    ch += a;

    return(0);
}
When compiled gives .....

Code: Select all

[email protected] ~ $ gcc -Wall -Wextra -Wconversion types.c 
types.c: In function ‘main’:
types.c:11:8: warning: conversion to ‘uint8_t’ from ‘int’ may alter its value [-Wconversion]
     ch += a;
        ^
[email protected] ~ $ 

Ironically in the code where this occurs I could just as easily (and arguably more correctly) have used "|=" in place of "+=".

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

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 8:31 am

Annoying isn't it! Especially as in your example the compiler must know that 0x10 + 0x20 is perfectly safe.

As you know, in C types smaller than int are promoted to int for the expression, which is for processors like ARM that cannot correctly do 8-bit arithmetic (they only have 32-bit registers).

The compiler then warns because 255 + 255 (say) will overflow and the result 510 cannot be saved in a uint8_t without loss.
I don't know any way of making that go away, but as you spotted the three bitwise logical operators | & and ^ can never overflow so do not attract a warning.

Sometimes I just give in and use int or unsigned int for the operands.
Ironically in the code where this occurs I could just as easily (and arguably more correctly) have used "|=" in place of "+=".
If its more correct, or more natural, to use |= then problem solved!

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 9:05 am

jahboater wrote:Annoying isn't it! Especially as in your example the compiler must know that 0x10 + 0x20 is perfectly safe.

As you know, in C types smaller than int are promoted to int for the expression, which is for processors like ARM that cannot correctly do 8-bit arithmetic (they only have 32-bit registers).
I've never really bothered too much about these "type conversion" things until you set me off along this "path of enlightenment" (so yes I'm blaming you :lol: ) , preferring instead to think about the limits of the values in variables and using appropriate types. This has worked fine for me for over 30 years. But I must admit that code that compiles cleanly with the long list of warnings enabled somehow feels "better".

The compiler then warns because 255 + 255 (say) will overflow and the result 510 cannot be saved in a uint8_t without loss.
I don't know any way of making that go away, but as you spotted the three bitwise logical operators | & and ^ can never overflow so do not attract a warning.

Sometimes I just give in and use int or unsigned int for the operands.
The only solution I've found that is warning free is to replace "ch += a;" with "ch = (uint8_t) (ch + a);" which seems nonsensical until you remember the integer promotion rules mentioned earlier).
Ironically in the code where this occurs I could just as easily (and arguably more correctly) have used "|=" in place of "+=".
If its more correct, or more natural, to use |= then problem solved!
I must admit to being a bit inconsistent in this respect. Sometimes I use "+=" for setting bits and other times I use "|=". Now I have a good reason to be consistent !

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

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 9:42 am

PeterO wrote: The only solution I've found that is warning free is to replace "ch += a;" with "ch = (uint8_t) (ch + a);" which seems nonsensical until you remember the integer promotion rules mentioned earlier).
I think thats the only way of doing it - if ch really must be 8 bits.

or perhaps this horrid macro!

#define add(a,b) (a = (typeof(a))(a + b))

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 9:51 am

jahboater wrote:
PeterO wrote: The only solution I've found that is warning free is to replace "ch += a;" with "ch = (uint8_t) (ch + a);" which seems nonsensical until you remember the integer promotion rules mentioned earlier).
I think thats the only way of doing it - if ch really must be 8 bits.
Well that's an interesting point ! The "character" held in ch is actually only 5 bits (it represents a character form a length of paper tape from an 1960's computer) so uint8_t seems the most appropriate type to use.

I'm of such an an age that using 32 or 64 bits to hold a 5 bit value is an offensive waste of memory to me :roll: :lol:

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

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 9:53 am

PeterO wrote:preferring instead to think about the limits of the values in variables and using appropriate types. This has worked fine for me for over 30 years.
Yes indeed. And that sort of thought is still needed. If you are going to override a warning with a cast you are saying that you have actually done so.

I sometimes do things like this to justify a cast.

int a;
unsigned int b;

assert( a >= 0 );
b = (unsigned int)a;

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 10:08 am

PeterO wrote: Well that's an interesting point ! The "character" held in ch is actually only 5 bits (it represents a character form a length of paper tape from an 1960's computer) so uint8_t seems the most appropriate type to use.
Upper case only! (why not "char" by the way? reads better and sign extension will never be an issue).
I'm of such an an age that using 32 or 64 bits to hold a 5 bit value is an offensive waste of memory to me :roll: :lol:
Ditto. But its only an issue when stored as a string/array. Individual values in functions will be in a 32-bit register anyway.

I think we are well past the "5 minutes to learn C" now :)

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 10:23 am

jahboater wrote:
PeterO wrote:preferring instead to think about the limits of the values in variables and using appropriate types. This has worked fine for me for over 30 years.
Yes indeed. And that sort of thought is still needed. If you are going to override a warning with a cast you are saying that you have actually done so.
Yes, I hadn't thought about it like that, good point.

I sometimes do things like this to justify a cast.

int a;
unsigned int b;

assert( a >= 0 );
b = (unsigned int)a;
I can see where you're going with that, but it kind of says "I'm actually not sure that a will always be positive and I can't be bothered to work out when it might be negative, so I'm not going to worry about it until it actually does become negative" :shock:

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

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 10:46 am

PeterO wrote:

I sometimes do things like this to justify a cast.

int a;
unsigned int b;

assert( a >= 0 );
b = (unsigned int)a;
I can see where you're going with that, but it kind of says "I'm actually not sure that a will always be positive and I can't be bothered to work out when it might be negative, so I'm not going to worry about it until it actually does become negative" :shock:
Now you are making me think! It does indeed look bad. Hmm.
It was intended to combine (a) documentation, and (b) in case some future code change caused a to be negative, and possibly (c) to help the GCC data flow analyzer.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 11:39 am

jahboater wrote:
PeterO wrote: I can see where you're going with that, but it kind of says "I'm actually not sure that a will always be positive and I can't be bothered to work out when it might be negative, so I'm not going to worry about it until it actually does become negative" :shock:
Now you are making me think! It does indeed look bad. Hmm.
It was intended to combine (a) documentation, and (b) in case some future code change caused a to be negative, and possibly (c) to help the GCC data flow analyzer.
I can see the point of adding "assert()" statements early in a development as a way to prompt the programmer that there is an unhanded case that still needs to be considered and handled in the code.
But once the code to handle the situation has been added I think the previous assert statement should be removed otherwise they could cause confusion to later readers as there is both an assert(conditionX) and code to handle conditionX.

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

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 12:34 pm

PeterO wrote:I can see the point of adding "assert()" statements early in a development as a way to prompt the programmer that there is an unhanded case that still needs to be considered and handled in the code.
I think its two differing ways of thinking about assert.

The above is not why I put them in (I use TODO's for that :) ). I add them in case ten years later a maintenance code change causes conditionX, or a bug causes conditionX (in which case the assert might help catch the problem early making debugging easier, or may even catch a latent bug).

From a documentation point of view it is a verifiable statement that I believe xxx condition is true at this point in the code.

You could reasonably argue that code to deal with conditionX should always be present, but I think you have to draw a line somewhere and I do always strive to simplify code.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 2:05 pm

Where do you stand on putting the previously necessary "extern" in front of function prototypes in header files ?

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

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 26070
Joined: Sat Jul 30, 2011 7:41 pm

Re: Writing clean code isn't hard!

Wed May 03, 2017 2:33 pm

PeterO wrote: I'm of such an an age that using 32 or 64 bits to hold a 5 bit value is an offensive waste of memory to me :roll: :lol:
PeterO
Me too, but then I remember than on ARM, 32bit access is MUCH faster. So I feel OK again, and just use int.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 2:38 pm

jamesh wrote:
PeterO wrote: I'm of such an an age that using 32 or 64 bits to hold a 5 bit value is an offensive waste of memory to me :roll: :lol:
PeterO
Me too, but then I remember than on ARM, 32bit access is MUCH faster. So I feel OK again, and just use int.
My code will (eventually) run on Raspbian and 64 bit PC Linux so it's probably going to be wrong on one platform or another :lol:

PeterO

PS: Now upto 10,300 lines of code with no warnings.
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: 5475
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Wed May 03, 2017 3:00 pm

PeterO wrote:Where do you stand on putting the previously necessary "extern" in front of function prototypes in header files ?
You've got me there, I didn't know it had changed :-(

I use "static" if the actual function definition is within the same compilation unit or "extern" iff its in a different one.
Last edited by jahboater on Wed May 03, 2017 3:00 pm, edited 1 time in total.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 3:00 pm

PeterO wrote:Where do you stand on putting the previously necessary "extern" in front of function prototypes in header files ?

PeterO
I don't think it matters anymore since functions are extern by default. Were they ever not? Possibly old pre-ansi compilers may have not given them external linkage without it. Personally I still declare them as extern in headers (out of habit if nothing else).

<Edit> Just looked in K&R C (2nd edition), that gives an example where functions are declared in a header without using extern, so that's ~30 years of not needing it at least (yet gcc still provides the standard libraries with explicit extern function prototypes).
She who travels light — forgot something.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 3:32 pm

PeterO wrote: My code will (eventually) run on Raspbian and 64 bit PC Linux so it's probably going to be wrong on one platform or another :lol:

PS: Now upto 10,300 lines of code with no warnings.
I think you will be fine, you have done it the right way round (32-bit first).

long a;
unsigned int b;
a = b; // will raise a warning on 32-bit, but not on 64-bit.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 4:36 pm

jahboater wrote:I think you will be fine, you have done it the right way round (32-bit first).
I can't do work like this on a single headed machine, there's just not enough desktop space to see DevHelp, 2 or 3 emacs frames, terminal for make/run. Then there's another virtual desktop with multiple browser windows open for google, stack overflow, twitter, Pi Forums.

So I'm doing it the wrong way round, MINT-17 on AMD-64 first , Raspbian on Pi later.

PeterO

PS: Latest code draws and animates this:
Image
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: 5475
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Writing clean code isn't hard!

Wed May 03, 2017 4:54 pm

Paeryn wrote: <Edit> Just looked in K&R C (2nd edition), that gives an example where functions are declared in a header without using extern, so that's ~30 years of not needing it at least (yet gcc still provides the standard libraries with explicit extern function prototypes).
Perhaps its to help readability - it clearly shows the function has external linkage. int foo() doesn't.
(maybe like "auto n" - we all know its an int but "int n" is more helpful).

My first edition K&R has the same - 39 years.

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

Re: Writing clean code isn't hard!

Wed May 03, 2017 5:43 pm

PeterO wrote: PS: Latest code draws and animates this:
Image
Impressive. I guess it shows the paper tape running through the reader and the algol on it being printed out at the same time.

Return to “C/C++”