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

Re: How would you ...... in C ?

Mon May 22, 2017 4:27 pm

jahboater wrote:trivia (but given your sig ;) ) ....
int main(void)
is a valid signature for main() and is more readable than
int main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv)
IMO "int main(void)" is for embedded systems where there are no command line arguments to pass :roll:
There's two ;; after the loop in main.
I shall rectify that grievous mistake immediate , and then go out and flog myself :lol: :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

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: How would you ...... in C ?

Mon May 22, 2017 5:00 pm

PeterO wrote:I like the "state machine" approach. Here's my take on it....
That fails if the first character not to match is the correct first key of the sequence. For example "12123#". That's why mine is complicated with the gotos. Nice compact state machine though.

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

Re: How would you ...... in C ?

Mon May 22, 2017 5:14 pm

rurwin wrote:
PeterO wrote:I like the "state machine" approach. Here's my take on it....
That fails if the first character not to match is the correct first key of the sequence. For example "12123#". That's why mine is complicated with the gotos. Nice compact state machine though.

Code: Select all

	    // Go back to start on a wrong key
	    nextToMatch = (keypressed == combination[0]) ? 1 : 0;
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: 2636
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: How would you ...... in C ?

Mon May 22, 2017 6:46 pm

PeterO wrote:
Paeryn wrote:I wasn't sure if the intended behaviour of overly long entries that ended with the correct sequence was to be considered valid. I originally had it that way and then decided it shouldn't accept e.g. 5123# so I changed my implementation to require exactly 123#, with the # resetting the entry when an invalid code was tried.
Fair enough. We didn't have a specification to work to ! And clean code too, but not quite "clean and shiny code" by jahboater's standard ;) (I'm not taking the blame for this :lol: )

Code: Select all

gcc $ALLCFLAGS -o combination2 combination2.c  -lncurses
combination2.c:24:5: warning: no previous prototype for ‘readKeyString’ [-Wmissing-prototypes]
 int readKeyString(const char *key)
     ^


PeterO
Aww shucks... :oops: I don't use -Wmissing-prototypes. I'll add static to that.
She who travels light — forgot something.

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

Re: How would you ...... in C ?

Mon May 22, 2017 7:07 pm

Paeryn wrote:Aww shucks... :oops: I don't use -Wmissing-prototypes. I'll add static to that.
We're all friends here (well most of us are!) No need to be embarrassed :lol:

I must admit that I did consider posting my reply before compiling with the big set of warnings enabled, but I was sure someone would pull me up with a list of warnings if I didn't ! Actually "doing it properly" is now becoming easier as I'm starting to recognise the things that the compiler will picked up as I write them.

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: 2636
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: How would you ...... in C ?

Mon May 22, 2017 9:40 pm

PeterO wrote:
Paeryn wrote:Aww shucks... :oops: I don't use -Wmissing-prototypes. I'll add static to that.
We're all friends here (well most of us are!) No need to be embarrassed :lol:

I must admit that I did consider posting my reply before compiling with the big set of warnings enabled, but I was sure someone would pull me up with a list of warnings if I didn't ! Actually "doing it properly" is now becoming easier as I'm starting to recognise the things that the compiler will picked up as I write them.

PeterO
Yes, but since I've been involved in the writing clean code thread... :) I don't tend to use many warnings other than -Wall and -Wextra, even then not all the time. To be honest I didn't even use them when I tested the code, but I did write it with my compiler head on (Aunt Sally made me change it first ;) )
She who travels light — forgot something.

jahboater
Posts: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ?

Wed May 24, 2017 1:38 pm

PeterO wrote: IMO "int main(void)" is for embedded systems where there are no command line arguments to pass
OK fair enough, how about something like this then (another way to make it portable)?

Code: Select all

#ifdef __GNUC__
#define pure      __attribute__ ((pure))
#define unused    __attribute__ ((unused))
#define packed    __attribute__ ((packed))
#define inline    __inline__ __attribute__ ((always_inline))
#else
#define pure      /**/
#define unused    /**/
#define packed    /**/
#define inline    /**/
#endif
.....................
int main( int argc unused, char **argv unused )
In practice though, most GCC extensions are widely supported by other prominent compilers.

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

Re: How would you ...... in C ?

Wed May 24, 2017 2:51 pm

To be honest I don't like macro's like those because they are not standard and thus are not documented anywhere. I know it's only a matter of finding the definition, but it's an extra step that a inexperienced programmer may not take.
The full version e.g. "__attribute__((unused))", tells you everything you (and the compiler) need to know. No need to hunt around for some non-standard definitions possibly in a header file somewhere.

And the non-gcc versions of your macros are just confusing because they don't do what they say they do e.g. functions that seem to be declared to be inline won't be inline and variables marked as unused may still generate "unused variable" 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

jahboater
Posts: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ?

Wed May 24, 2017 3:31 pm

PeterO wrote:And the non-gcc versions of your macros are just confusing because they don't do what they say they do e.g. functions that seem to be declared to be inline won't be inline and variables marked as unused may still generate "unused variable" warnings.
But the code will still work, still compile, and still be valid C. They are just fall-backs. None of the non-gcc versions stop it working, or even affect the "correctness".

Pure is just advice to the optimizer (which may be ignored by the compiler anyway).
Unused - yes may produce warnings, but the full version will not even compile!
Packed - well maybe, but if code depends on the offsets within a struct, or the size of an enum, its pretty poor anyway! (see offsetof)
Inline - it will just be slower and possibly bigger but will still run and still be correct. (more useful perhaps is "noinline" which I use for interrupt handlers).

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

Re: How would you ...... in C ?

Wed May 24, 2017 3:51 pm

jahboater wrote:
PeterO wrote:And the non-gcc versions of your macros are just confusing because they don't do what they say they do e.g. functions that seem to be declared to be inline won't be inline and variables marked as unused may still generate "unused variable" warnings.
But the code will still work, still compile, and still be valid C. They are just fall-backs for the unlikely event that I stop using gcc. None of the non-gcc versions stop it working, or even affect the "correctness".
Maybe so, but you have source code that says "this function is inlined" but in fact it is not. I don't like having to guess what source code means, which by the way is why I think I have so much trouble with C++. I find it incomprehensible.
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: 2636
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: How would you ...... in C ?

Wed May 24, 2017 4:36 pm

I'd take exception with the #define inline, since C99 inline is a keyword in the language. Not a good idea to go around redefining it as something else.
She who travels light — forgot something.

jahboater
Posts: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ?

Wed May 24, 2017 5:41 pm

Paeryn wrote:I'd take exception with the #define inline, since C99 inline is a keyword in the language. Not a good idea to go around redefining it as something else.
Yes of course.
My definition has the same meaning, but makes it stronger.
I just tried the plain C99 keyword in a program and and 38 less functions were inlined.
Not sure what I would call the macro other than "inline" though - it reads easily as it is.

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

Re: How would you ...... in C ?

Wed May 24, 2017 5:45 pm

jahboater wrote:
Paeryn wrote:I'd take exception with the #define inline, since C99 inline is a keyword in the language. Not a good idea to go around redefining it as something else.
Yes of course.
My definition has the same meaning, but makes it stronger.
I just tried the plain C99 keyword in a program and and 38 less functions were inlined.
Not sure what I would call the macro other than "inline" though - it reads easily as it is.
If it's part of language since C99, why do you need the macro at all ?
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: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ?

Wed May 24, 2017 5:56 pm

PeterO wrote:
jahboater wrote:
Paeryn wrote:I'd take exception with the #define inline, since C99 inline is a keyword in the language. Not a good idea to go around redefining it as something else.
Yes of course.
My definition has the same meaning, but makes it stronger.
I just tried the plain C99 keyword in a program and and 38 less functions were inlined.
Not sure what I would call the macro other than "inline" though - it reads easily as it is.
If it's part of language since C99, why do you need the macro at all ?
PeterO
Good question.
The "always inline" bit forces the compiler to actually inline things, nice and simple.
The keyword seems to be ignored in about 3/4 of cases!
I think I should understand exactly why that is ...

I would much rather use the keyword.

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

Re: How would you ...... in C ?

Wed May 24, 2017 9:24 pm

jahboater wrote:The "always inline" bit forces the compiler to actually inline things, nice and simple.
The keyword seems to be ignored in about 3/4 of cases!
I think I should understand exactly why that is ...

I would much rather use the keyword.
Well it is allowed to ignore the inline hint. ;-) Possibly the compiler decided that inlining the code wasn't worth it most of the time. Usually the compiler is in a good place to see the costs. Unfortunately -fopt-info-optimized doesn't seem to give any output but you can get early inlining information by requesting internal dumps. -fdump-tree-einline has lots of data (including the internal representation of the code). At the start of each function it tells you which functions were considered for inlining and whether they were or not (you can get more info with -fdump-tree-einline-details).

Then again, there's more data in -fdump-ipa-inline-details, that gives you information like (although it produces even bigger files, lots of data) :-

Code: Select all

  not inlinable: rshapes/51 -> rseed/50, function not declared inline and code size would grow
  not inlinable: main/56 -> sunearth/52, call is unlikely and code size would grow
I didn't define rseed inline, the optimiser thought about it and decided it wasn't worth it. I did ask it to inline sunearth, the optimiser decided again it wasn't worth it even though I asked for it.

<Edit>
These options aren't really meant for regular users of gcc, more for developers of gcc to see what's going on, and it's been quite a few years since I really looked into it's inner workings.
She who travels light — forgot something.

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

Re: How would you ...... in C ?

Thu May 25, 2017 6:53 am

I'm resisting trying those switches on some code as they look like they lead down a deep, dark rabbit hole :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

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

Re: How would you ...... in C ?

Thu May 25, 2017 9:16 am

PeterO wrote:I'm resisting trying those switches on some code as they look like they lead down a deep, dark rabbit hole :lol:
PeterO
Very deep... :o I'm getting the urge to look into the optimisation passes again. It was probably version 2 last time I delved into it, lots of changes since then but you learn so much on what is going on under the hood.
She who travels light — forgot something.

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

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 9:26 am

Talking of rabbit holes... I looked at the assembler versions of some short bits of my code yesterday. Difference between no-optimisation and just -O was huge ! In one case the compiler seemed to have worked out the return value from a function was always going to be 4 and just replaced the whole function with a load immediate 8-) (This was on X86_64 machine).

It was a useful exercise though, I was able to tidy up some code by removing some superfluous intermediate variables used to simply hold pointers that had been cast from one type to another. Much better solution was to use a union.
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: 2636
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 9:37 am

PeterO wrote:Talking of rabbit holes... I looked at the assembler versions of some short bits of my code yesterday. Difference between no-optimisation and just -O was huge ! In one case the compiler seemed to have worked out the return value from a function was always going to be 4 and just replaced the whole function with a load immediate 8-) (This was on X86_64 machine).

It was a useful exercise though, I was able to tidy up some code by removing some superfluous intermediate variables used to simply hold pointers that had been cast from one type to another. Much better solution was to use a union.
PeterO
No optimisation is always big code. Things like every write to a variable actually stores it to memory and a read will read it back from memory again, even if no other instructions took place in between. Quite often (more so on ARM than x86) some local variables can get optimised out of ever requiring physical memory storage with optimisations on. It's better to leave your code easy to read and allow the optimiser to do it's job, sometimes you can make it harder for the compiler by trying to out guess it.
She who travels light — forgot something.

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

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 9:46 am

Paeryn wrote: It's better to leave your code easy to read and allow the optimiser to do it's job, sometimes you can make it harder for the compiler by trying to out guess it.
The new code is shorter, clearer and produces slightly shorter assembler.
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: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 10:12 am

PeterO wrote:Talking of rabbit holes... I looked at the assembler versions of some short bits of my code yesterday.
If anyone is looking at the assembler produced by the compiler, I strongly suggest GCC 7.1 if you can install it. Apart from better code for ARM, they have finally fixed "-fverbose-asm" in 7.1. It now produces the source lines interspersed with the emitted assembler for each line, which is very helpful (MSVC did this decades ago, and I had aways assumed GCC didn't because the high levels of optimization made it meaningless. Well it works now). I use -Os for the small size mostly, but happily the code produced by -Os is more like a human would write. GCC 7.1 also has quite a few new warning options for PeterO to try :) I can post a script to install it.

Code: Select all

#
#  Assembler output.
#
ASMFLAGS = -S -Wa,-acglhdns,--keep-locals -fverbose-asm -fkeep-inline-functions -frandom-seed=1234 $(CFLAGS)
-fkeep-inline-functions doesnt seem to work, random seed was an attempt to make the output reproducible to make diff's work better.

Well what a deep hole Paeryn has introduced! Thanks for all that info!

These options are not documented (at least not in man gcc). Very interesting. Lots to study from -fdump-tree-einline-details and -fdump-ipa-inline-details which do produce huge files that are quite hard to understand.

jahboater
Posts: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 10:35 am

Paeryn wrote: It's better to leave your code easy to read and allow the optimizer to do it's job, sometimes you can make it harder for the compiler by trying to out guess it.
Definitely agree here.

Simplicity and readability are always the primary goal.
In time though you do learn various methods that generally produce better code, from obvious things like do while instead of while to ... well thats another rabbit hole.

The compiler is pretty clever with recent versions. For example if you had at the start of a function "if( n < 5 ) return" say, later code would know n is always non-zero so while loops controlled by n get converted to do while loops and so on.

But, yes, in general trust the optimizer.

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

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 10:39 am

jahboater wrote:
PeterO wrote:Talking of rabbit holes... I looked at the assembler versions of some short bits of my code yesterday.
If anyone is looking at the assembler emitted by the compiler, I strongly suggest GCC 7.1 if you can install it. Apart from better code for ARM, they have finally fixed "-fverbose-asm" in 7.1. It now produces the source lines interspersed with the emitted assembler for each line, which is very helpful (MSVC did this decades ago, and I had aways assumed GCC didn't because the high levels of optimization made it meaningless. Well it works now). I use -Os for the small size mostly, but happily the code produced by -Os is more like a human would write. GCC 7.1 also has quite a few new warning options for PeterO to try :) I can post a script to install it.

Code: Select all

 
#
#  Assembler output.
#
ASMFLAGS = -S -Wa,-acglhdns,--keep-locals -fverbose-asm -fkeep-inline-functions -frandom-seed=1234 $(CFLAGS)
Not all the above works, random seed was an attempt to make the output reproducible to make diff's work better.

Well what a deep hole Paeryn has introduced! Thanks for all that info!

These options are not documented (at least not in man gcc). Very interesting. Lots to study from -fdump-tree-einline-details and -fdump-ipa-inline-details which do produce huge files that are quite hard to understand.
They are documented (vaguely) in the online docs (under Developer options). There are a whole boat load of -fdump- options, one for every pass. Supposedly the -fopt-info-* options should produce output but the only pass that seems to use it is the vectoriser.
A lot of the info that the dumps produce is of little use unless you are debugging the passes or understand how the pass works but they do provide some insight in to what the compiler is up to.
Thanks for the heads up on -fverbose-asm, I'm sure it used to work (but that was years ago generating mips code).
She who travels light — forgot something.

jahboater
Posts: 4604
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 10:48 am

Paeryn wrote: Quite often (more so on ARM than x86) some local variables can get optimised out of ever requiring physical memory storage with optimisations on.
You should see ARM64 code. It has 31 64-bit registers (and a handy zero register) - very frequently functions require no stack at all.

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

Re: How would you ...... in C ? (+ other C discussions)

Thu May 25, 2017 10:59 am

jahboater wrote:
Paeryn wrote: Quite often (more so on ARM than x86) some local variables can get optimised out of ever requiring physical memory storage with optimisations on.
You should see ARM64 code. It has 31 64-bit registers (and a handy zero register) - very frequently functions require no stack at all.
One of the things I've been meaning to do for a while is install a 64 bit OS to play around with AArch64. I used to like SPARC with its sliding register window for function calls.
She who travels light — forgot something.

Return to “C/C++”