Reply by CBFalconer May 1, 20082008-05-01
Wilco Dijkstra wrote:
> "CBFalconer" <cbfalconer@yahoo.com> wrote: >> Wilco Dijkstra wrote: >>
... snip stuff on arithmetic shifts ...
>> >>> Compiler writers agree on most of these things, so in reality >>> these things are extremely well defined. Basically nobody cares >>> about what the C standard says exactly as long as their code >>> compiles. If it doesn't work on a particular compiler, it is >>> that compiler's fault. I know, I have dealt with angry customers >>> with millions of lines of code that didn't compile on our >>> expensive but strict ANSI C compiler... >> >> You need copies of the C standard to hand out. Most of those >> problems have been discussed here, so you have a good selection >> of immediate answers and suggestions available. > > Basically if some application works fine when compiled by various > compilers but not if compiler X is used, then it is compiler X > that is wrong, not the source code. The C standard is not relevant > if this kind of issue comes up, so handing out copies of the > standard doesn't help (it might be seen as an insult by paying > customers - they pay you to solve their problem, not to be told to > rewrite their code). > > The huge amount of existing source code defines the standard that > compilers must adhere to, not the official C standard. It may not > be ideal, but that is the way things are. I would like to see most > implementation defined behaviours explicitly defined (as compilers > agree on them anyway), various undefined behaviours defined and > many common compiler extensions standardized. It seems unlikely the > C/C++ committees will ever do the right thing...
If you have to build something to run on some users equipment and compiled on his compilers, that is one thing. Usually you have the choice of tools. Today most C systems make valiant efforts to be standard compatible, usually to C95, and document their failures. Some of those failures are due to the hardware proper. I can see no reason to shift signed variables, when unsigned is available. Every piece of code you write that adheres to the standard is that much more portable, and won't need rewriting for another application. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com **
Reply by Chris H May 1, 20082008-05-01
In message <WHiSj.65882$h65.55052@newsfe2-gui.ntli.net>, Wilco Dijkstra 
<Wilco_dot_Dijkstra@ntlworld.com> writes
> >"CBFalconer" <cbfalconer@yahoo.com> wrote in message >news:4811D3BC.EC3B4E67@yahoo.com... >> Wilco Dijkstra wrote: >>> "David Brown" <david@westcontrol.removethisbit.com> wrote: >>> >> ... snip ... >>> >>>> Is the rounding of shifts like this well defined in C? I can't >>>> remember the exact rules off-hand - perhaps that's why MISRA >>>> doesn't like right shifts of signed integers! >>> >>> No it's not well defined, just like most other things in C, but >>> who cares anyway?!? >>> >>> Compiler writers agree on most of these things, so in reality >>> these things are extremely well defined. Basically nobody cares >>> about what the C standard says exactly as long as their code >>> compiles. If it doesn't work on a particular compiler, it is >>> that compiler's fault. I know, I have dealt with angry customers >>> with millions of lines of code that didn't compile on our >>> expensive but strict ANSI C compiler... >> >> You need copies of the C standard to hand out. Most of those >> problems have been discussed here, so you have a good selection of >> immediate answers and suggestions available. > >Basically if some application works fine when compiled by various compilers >but not if compiler X is used, then it is compiler X that is wrong, not >the source >code.
Commercially this is true.
>The C standard is not relevant if this kind of issue comes up,
I agree. Basic is a good example of this. The world revolves around VB not ISO BASIC
>so handing >out copies of the standard doesn't help (it might be seen as an insult >by paying >customers -
Absolutely. You have to work with the tools available. Standard C is not "required" anywhere which is the problem. If it was legally required to have ISO-C compliant compilers then it would be a different matter.
>they pay you to solve their problem, not to be told to rewrite their >code).
Rewrite their code to a theoretical standard that is not implemented by the compilers.
>The huge amount of existing source code defines the standard that compilers >must adhere to, not the official C standard. It may not be ideal, but >that is the >way things are.
I agree. The standard should be regularising what we have not going off at a tangent.
>I would like to see most implementation defined behaviours >explicitly defined (as compilers agree on them anyway), various undefined >behaviours defined and many common compiler extensions standardized. >It seems unlikely the C/C++ committees will ever do the right thing...
I agree... though there is a light at the end of the tunnel as 10 years on virtually no one has implemented C99. However as there are a lot of moves to be MISRA-C:2004 compliant the C panels have started to realise that unless they come back to the mainstream ISO-C will become as irrelevant as ISO BASIC. . -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply by Wilco Dijkstra May 1, 20082008-05-01
"CBFalconer" <cbfalconer@yahoo.com> wrote in message news:4811D3BC.EC3B4E67@yahoo.com...
> Wilco Dijkstra wrote: >> "David Brown" <david@westcontrol.removethisbit.com> wrote: >> > ... snip ... >> >>> Is the rounding of shifts like this well defined in C? I can't >>> remember the exact rules off-hand - perhaps that's why MISRA >>> doesn't like right shifts of signed integers! >> >> No it's not well defined, just like most other things in C, but >> who cares anyway?!? >> >> Compiler writers agree on most of these things, so in reality >> these things are extremely well defined. Basically nobody cares >> about what the C standard says exactly as long as their code >> compiles. If it doesn't work on a particular compiler, it is >> that compiler's fault. I know, I have dealt with angry customers >> with millions of lines of code that didn't compile on our >> expensive but strict ANSI C compiler... > > You need copies of the C standard to hand out. Most of those > problems have been discussed here, so you have a good selection of > immediate answers and suggestions available.
Basically if some application works fine when compiled by various compilers but not if compiler X is used, then it is compiler X that is wrong, not the source code. The C standard is not relevant if this kind of issue comes up, so handing out copies of the standard doesn't help (it might be seen as an insult by paying customers - they pay you to solve their problem, not to be told to rewrite their code). The huge amount of existing source code defines the standard that compilers must adhere to, not the official C standard. It may not be ideal, but that is the way things are. I would like to see most implementation defined behaviours explicitly defined (as compilers agree on them anyway), various undefined behaviours defined and many common compiler extensions standardized. It seems unlikely the C/C++ committees will ever do the right thing...
>>> Would this be more correct? >>> >>> return ~((int) (((unsigned int) (~value)) >> shift); >>> >>> I haven't checked it - in particular, corner cases must be >>> checked. I'm just spouting ideas for the OP. >> >> That's right indeed (replacing the first return above). Of course >> this still gives you correct behaviour only on 2-complement's >> CPUs. So it adds a lot of overhead and bugs (given only the OP >> got it right first time) for no gain whatsoever... > > It's still fundamentally wrong - you can't guarantee unsigned to > signed casts, because an overflow may occur, and the result is > implementation defined behaviour.
You're quite right that all this does is replacing one kind of implementation defined behaviour with another - however any piece of non-trivial code relies on implementation defined behaviour given the C standard is so badly defined. As I've explained before, you can rely on most implementation defined behaviours to be implemented identically on the vast majority compilers. So the whole exercise is pointless as signed shifts work correctly in the first place. Wilco
Reply by stephen April 29, 20082008-04-29
On 29 Apr, 21:57, Nils <n.pipenbri...@cubic.org> wrote:

> int init_the_big_library_lebowsky (foo *bar) > { > if (!init (sub_system1(bar)) goto failed1; > if (!init (sub_system2(bar)) goto failed2; > if (!init (sub_system3(bar)) goto failed3; > if (!init (sub_system4(bar)) goto failed4; > if (!init (sub_system5(bar)) goto failed5; > if (!init (sub_system6(bar)) goto failee6; > if (!init (sub_system7(bar)) goto failed7; > if (!init (sub_system8(bar)) goto failed8; > > // we did it! > return (E_SUCCESS_CODE); > > failed8: { de_init_subsys7(); return ("E_FUCKUP7\n"); } > failed7: { de_init_subsys6(); return ("E_FUCKUP6\n"); } > failed6: { de_init_subsys5(); return ("E_FUCKUP5\n"); } > failed5: { de_init_subsys4(); return ("E_FUCKUP4\n"); } > failed4: { de_init_subsys3(); return ("E_FUCKUP3\n"); } > failed3: { de_init_subsys2(); return ("E_FUCKUP2\n"); } > failed2: { de_init_subsys1(); return ("E_FUCKUP1\n"); } > failed1: { return ("E_FUCKUP=DF\n"); }
Isn't the point that you "de-init" everything you init, so the returns after the failed cases are wrong? It seems to me that you could benefit from some structure here: int init_the_big_library_lebowsky (foo *bar) { static const struct { int (*init)(foo*); void (*de_init)(void); } sys[] =3D { {init_sub_system0, de_init_subsys0,}, {init_sub_system1, de_init_subsys1,}, /* ... */ }; int i; for (i =3D 0; i < NELEMS(sys); i++) { if (! (*sys[i].init)(bar)) { // walk back "de-initialising" everything. while (--i >=3D 0) { (*sys[i].de_init)(); } return E_ERR; } } return E_OK; } I wouldn't quite adopt that style in production code, but I stand by the idea. The code only needs to be made right once and adding a new "sub system" is trivial. (I neither tested it, nor proved it correct.) stephen
Reply by Walter Banks April 29, 20082008-04-29

Nils wrote:

> Folks, > > I always face the "goto would be nice and neat here" problem in all my > library initialization routines. > > It's somewhat identical to the "file open" thing CBFalconer postet > elsewhere, except that I don't just open 4 files. I initialize several > sub-systems and all sub-system build up onto each other. So subsystem N > must never be initialized unless subystem N-1 succeded. > > I think we've all have written this kind of code. > > My what I *would* like to write for such a "master library-init > functions" would be: > > int init_the_big_library_lebowsky (foo *bar) > { > if (!init (sub_system1(bar)) goto failed1; > if (!init (sub_system2(bar)) goto failed2; > if (!init (sub_system3(bar)) goto failed3; > if (!init (sub_system4(bar)) goto failed4; > if (!init (sub_system5(bar)) goto failed5; > if (!init (sub_system6(bar)) goto failee6; > if (!init (sub_system7(bar)) goto failed7; > if (!init (sub_system8(bar)) goto failed8; > > // we did it! > return (E_SUCCESS_CODE); > > failed8: { de_init_subsys7(); return ("E_FUCKUP7\n"); } > failed7: { de_init_subsys6(); return ("E_FUCKUP6\n"); } > failed6: { de_init_subsys5(); return ("E_FUCKUP5\n"); } > failed5: { de_init_subsys4(); return ("E_FUCKUP4\n"); } > failed4: { de_init_subsys3(); return ("E_FUCKUP3\n"); } > failed3: { de_init_subsys2(); return ("E_FUCKUP2\n"); } > failed2: { de_init_subsys1(); return ("E_FUCKUP1\n"); } > failed1: { return ("E_FUCKUP&#4294967295;\n"); } > } > > Yes, you counted right: 8 gotos. But the program flow is as easy as it > could be. > > Compare this to a 8 level deep nested tree with " '{'-char must match > the same line"-rule obeyed, and the "must not put more than 4 levels of > nesting within a function-rule obeyed as well. > > My innocent "initialize the big-library"-function has to be splitted > into at least two functions and will be expanded to roughly 100 lines of > dada-code. > > The orignal - also it uses goto - is much easier to understand. > > Will the MISRA-conformant function become more understandable? I don't > think so. > > For init-orgies like this goto's are a god-sent. > > Nils
I probably missed something. I am not sure why this doesn't also solve the problem and gets rid of the goto's. The generated code size would be very similar. int init_the_big_library_lebowsky (foo *bar) { if (!init (sub_system1(bar)) { return ("E_FUCKUP&#4294967295;\n"); } if (!init (sub_system2(bar)) { de_init_subsys1(); return ("E_FUCKUP1\n"); } if (!init (sub_system3(bar)) { de_init_subsys2(); return ("E_FUCKUP2\n"); } if (!init (sub_system4(bar)) { de_init_subsys3(); return ("E_FUCKUP3\n"); } if (!init (sub_system5(bar)) { de_init_subsys4(); return ("E_FUCKUP4\n"); } if (!init (sub_system6(bar)) { de_init_subsys5(); return ("E_FUCKUP5\n"); } if (!init (sub_system7(bar)) { de_init_subsys6(); return ("E_FUCKUP6\n"); } if (!init (sub_system8(bar)) { de_init_subsys7(); return ("E_FUCKUP7\n"); } // we did it! return (E_SUCCESS_CODE); } w..
Reply by Nils April 29, 20082008-04-29
Folks,

I always face the "goto would be nice and neat here" problem in all my 
library initialization routines.

It's somewhat identical to the "file open" thing CBFalconer postet 
elsewhere, except that I don't just open 4 files. I initialize several 
sub-systems and all sub-system build up onto each other. So subsystem N 
must never be initialized unless subystem N-1 succeded.


I think we've all have written this kind of code.



My what I *would* like to write for such a  "master library-init 
functions" would be:

int init_the_big_library_lebowsky (foo *bar)
{
   if (!init (sub_system1(bar)) goto failed1;
   if (!init (sub_system2(bar)) goto failed2;
   if (!init (sub_system3(bar)) goto failed3;
   if (!init (sub_system4(bar)) goto failed4;
   if (!init (sub_system5(bar)) goto failed5;
   if (!init (sub_system6(bar)) goto failee6;
   if (!init (sub_system7(bar)) goto failed7;
   if (!init (sub_system8(bar)) goto failed8;

   // we did it!
   return (E_SUCCESS_CODE);

   failed8: { de_init_subsys7(); return ("E_FUCKUP7\n"); }
   failed7: { de_init_subsys6(); return ("E_FUCKUP6\n"); }
   failed6: { de_init_subsys5(); return ("E_FUCKUP5\n"); }
   failed5: { de_init_subsys4(); return ("E_FUCKUP4\n"); }
   failed4: { de_init_subsys3(); return ("E_FUCKUP3\n"); }
   failed3: { de_init_subsys2(); return ("E_FUCKUP2\n"); }
   failed2: { de_init_subsys1(); return ("E_FUCKUP1\n"); }
   failed1: { return ("E_FUCKUP&#4294967295;\n"); }
}


Yes, you counted right: 8 gotos. But the program flow is as easy as it 
could be.

Compare this to a 8 level deep nested tree with " '{'-char must match 
the same line"-rule obeyed, and the "must not put more than 4 levels of 
nesting within a function-rule obeyed as well.

My innocent "initialize the big-library"-function has to be splitted 
into at least two functions and will be expanded to roughly 100 lines of 
dada-code.

The orignal - also it uses goto - is much easier to understand.

Will the MISRA-conformant function become more understandable? I don't 
think so.

For init-orgies like this goto's are a god-sent.

Nils
Reply by Chris H April 29, 20082008-04-29
In message 
<f0c87e4b-e426-4043-bce7-2de20250092d@b1g2000hsg.googlegroups.com>, 
stephen <stephenbennyhat@gmail.com> writes
>On 26 Apr, 07:57, Chris H <ch...@phaedsys.org> wrote: > >> Intestinally the "goto" is bad" came from a paper by Dykstra (not Wilco >> :-) and AFAIK no one has really challenged it but just taken it as read. > >See Donald Knuth (1974). "Structured Programming with Goto >Statements". Computing Surveys 6 (4): 261&ndash;301. >(e.g., http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf) >Also available in "Literate Programming" (ISBN 0-937073-80-6).
Many thanks. I will raise this at the next MISRA-C meeting. -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply by stephen April 29, 20082008-04-29
On 26 Apr, 07:57, Chris H <ch...@phaedsys.org> wrote:

> Intestinally the "goto" is bad" came from a paper by Dykstra (not Wilco > :-) and AFAIK no one has really challenged it but just taken it as read.
See Donald Knuth (1974). "Structured Programming with Goto Statements". Computing Surveys 6 (4): 261=96301. (e.g., http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf) Also available in "Literate Programming" (ISBN 0-937073-80-6). stephen
Reply by Steve at fivetrees April 28, 20082008-04-28
"CBFalconer" <cbfalconer@yahoo.com> wrote in message 
news:4815392F.5A73CD1E@yahoo.com...
> Steve at fivetrees wrote: >> "Chris H" <chris@phaedsys.org> wrote: >> > ... snip ... >> >>> However as with all things there are a few exceptions where got >>> is the cleanest solution. In those cases you need to deviate and >>> be able to stand up in court in 3 years time with your deviation. >> >> Sorry, but I disagree. There are always - ALWAYS - logically- >> equivalent structured alternatives to goto, which will not bite >> your ass anywhere near as badly. > > Those equivalents are not free. General implementation requires > the addition of flag variables. This was proven about 50 years > ago.
Absolutely. And it's a small price to pay. Given a choice between goto and a flag (or state) variable or two, guess which one I'd choose ;). Not because of religion, but because of clarity. Steve
Reply by Mel April 28, 20082008-04-28
Chris H wrote:

> Whilst everyone has (should have) a gut feeling that go to is bad there > is no empirical evidence as there is for other things. I would be > delighted if you could provide some. Your anecdote above is just that. > Not solid evidence.
The structured programming revolution of the '70s has cleaned up to the point that few people have seen goto-based code. For proof by personal revelation, check http://ftp.stratus.com/vos/multics/pg/moo.pl1 It's actually a good program for its day, pre Boehm and Jacopini. Trying to make a change, finding a certain place to put new code, is surprisingly hard -- not impossible, of course. Donald Knuth's vindication of some goto statements is at http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf Mel.