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

Re: Solution to X-Toolkit and portability.

Sun Nov 20, 2016 8:55 pm

DavidS wrote:

Code: Select all

static void poll(void)
{
  for(;;){    // Our very simple poll loop.

    const int rc = Wimp_Poll( MIN_POLL, workspace );

    if( rc == 6 )  // mouse click on IconBar Icon quit.
      if( WorkSpace[3] == -2 ) break;
    else if( rc == 17 || rc == 18 )  // User messages, quit if quit message.
      if( workspace[4] == 0 ) break;
  }
}
I suspect you will need the extra curly brackets otherwise the else might apply to the wrong if!

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Sun Nov 20, 2016 9:46 pm

jahboater wrote:
DavidS wrote:

Code: Select all

static void poll(void)
{
  for(;;){    // Our very simple poll loop.

    const int rc = Wimp_Poll( MIN_POLL, workspace );

    if( rc == 6 )  // mouse click on IconBar Icon quit.
      if( WorkSpace[3] == -2 ) break;
    else if( rc == 17 || rc == 18 )  // User messages, quit if quit message.
      if( workspace[4] == 0 ) break;
  }
}
I suspect you will need the extra curly brackets otherwise the else might apply to the wrong if!
Look at where the simicolon is, a single statement per if statement, which in this case applies to the break, as the embeded if is part of the same statement.

Actualy it might be wrong.

Though I can see that from the point of readability.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Sun Nov 20, 2016 9:51 pm

jahboater wrote:and perhaps something like this which uses no stack,
and the icon is set up at compile time.

Code: Select all

 
int main( void ) {
  // Setup our IconBar Icon.
static const ICON_BLOCK Icon = {
  .window = -1,                  // The window is the IconBar.
  .x0 = 0, .y0 = 0,              // Minimum x and y coords of the Icon.
  .x1 = 0, .y1 = 64,             // Maximum x and y coords of the Icon.
  .flags = ICONF_BUTTONCLICK | ICONF_SPRITE,
  .data.text = BARICON_NAME
};

IconHandle = Wimp_CreateIcon( &Icon );
Now that is starting to look a lot like BASIC :) .

Though interesting way to initialize a structure, did not know you could do that. I thought it would have to be something like:

Code: Select all

static const ICON_BLOCK Icon = { -1, 0, 0, 64, 64, ICONF_BUTTONCLICK | ICONF_SPRITE, {BARICON_NAME }};
So thank you for that. Something new I did not know about C.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

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

Re: Solution to X-Toolkit and portability.

Sun Nov 20, 2016 10:11 pm

DavidS wrote: I thought it would have to be something like:

Code: Select all

static const ICON_BLOCK Icon = { -1, 0, 0, 64, 64, ICONF_BUTTONCLICK | ICONF_SPRITE, {BARICON_NAME }};
You can do that as well of course.

Note that any missing fields are set to zero.

It works for arrays as well, with a slightly different syntax.

{ 3, [23] = 8, .. }

sets element 23 to 8.

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 2:45 am

Before I ramble onto the overloading things, in your code you are using TRUE = -1, but comparisons return 1 when true, not -1. It doesn't matter if you just test against not being 0 but if you ever test against TRUE...

Code: Select all

    Run = (workspace[4] != 0);
when workspace[4] != 0 then Run = 1. This is why using <stdbool.h> is preferable, it defines the bool type and it's values true and false correctly.
DavidS wrote: I thought that you could not overload the (), [], ->, ., ?:, or unary * operators at all. Could you give a short example of how they are overloaded in a meaningful way?
You can't overload any of the following operators

Code: Select all

. .* ?: :: sizeof alignof typeid static_cast<> dynamic_cast<> const_cast<> reinterpret_cast<>
Other than * , ?: , sizeof , and :: I have never heard of those operators, I am guessing these are additions to C++ that I missed?
.* is used to call a member function using a pointer-to-member-function.

Code: Select all

#include <iostream>
using namespace std;

class Foo {
public:
    int function(int x) {return x*2;};
};

typedef int (Foo::*FooMemberFunc)(int x);

int main(void)
{
    Foo bar;
    FooMemberFunc ptr = &Foo::function;

    cout << (bar.*ptr)(4) << endl;
    return 0;
}
The [] operator can be used to give you array-like access (totally convoluted example)

Code: Select all

#include <iostream>

class List {
    static const int size = 3;
    int elements[size];
    int dummy;
public:
    List() 
        {
            for (auto &element : elements)
                element = 0;
            dummy = -99;
        }
    // Array access, any index outside the valid range will affect the dummy
    int &operator[](int el) {
        if (el >= 0 && el < size)
            return elements[el];
        else
            return dummy;
    }
};

int main(void)
{
    List list;
    list[1] = 4;
    list[-5] = 10; // Any index outside 0..2 sets/gets the dummy value
    for (int x = -1; x < 5; x++)
        std::cout << "list[" << x << "] = " << list[x] << std::endl;
    return 0;
}
Similarly operator() allows access via multiple parameters (so you could do the above with multi-dimensional access using list(1,2) = 4; to set list.element[1][2].
operator-> lets you define a function that returns a pointer to another object (which will then have -> applied)

Code: Select all

object->var;
becomes

Code: Select all

(object.operator->())->var;
Similarly operator* (dereferencing) can be overloaded, these two are typically use in making smart pointer types.

alignof was introduced in C++11, it returns the byte alignment a type needs

Code: Select all

cout << "char needs alignment of " << alignof(char) << endl
     << "pointer_to_char needs alignment of " << alignof(char*) << endl;
typeid lets you get the type of a variable, it returns a variable of type type_info (must #include <typeinfo> to use)

Code: Select all

#include <iostream>
#include <typeinfo>

int main(void)
{
    int x;
    long y, z;

    std::cout << "types of x and y are " << (typeid(x) == typeid(y) ? "the same" : "different" << std::endl;
    std::cout << "types of y and z are " << (typeid(y) == typeid(z) ? "the same" : "different" << std::endl;
    return 0;
}
The casts are all used to cast in different ways, static_cast inserts basic type conversions at compile-time, dynamic_cast is similar but is used for changing pointers and references at run-time, const_cast lets you change the const property, and reinterpret_cast is similar to a static_cast but won't emit any code to do type conversions. So a C cast done in C++ would be the same as a static_cast falling back to a reinterpret_cast if static_cast isn't valid (and also a const_cast if needs be). static_cast can change a float into an int but not a pointer into an int whereas reinterpret_cast can change a pointer into an int (providing an int is big enough to hold a pointer) but not a float into an int.
She who travels light — forgot something.

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 3:14 am

Paeryn wrote:Before I ramble onto the overloading things, in your code you are using TRUE = -1, but comparisons return 1 when true, not -1. It doesn't matter if you just test against not being 0 but if you ever test against TRUE...

Code: Select all

    Run = (workspace[4] != 0);
when workspace[4] != 0 then Run = 1. This is why using <stdbool.h> is preferable, it defines the bool type and it's values true and false correctly.
Ok something that has changed. Been a long time since I did the test of printing the result of comparisons, though it used to be -1 (makes more since on the CPU level of operating also).

Does not matter though as any non 0 value is true.
DavidS wrote: I thought that you could not overload the (), [], ->, ., ?:, or unary * operators at all. Could you give a short example of how they are overloaded in a meaningful way?
You can't overload any of the following operators

Code: Select all

. .* ?: :: sizeof alignof typeid static_cast<> dynamic_cast<> const_cast<> reinterpret_cast<>
Other than * , ?: , sizeof , and :: I have never heard of those operators, I am guessing these are additions to C++ that I missed?
.* is used to call a member function using a pointer-to-member-function.

Code: Select all

#include <iostream>
using namespace std;

class Foo {
public:
    int function(int x) {return x*2;};
};

typedef int (Foo::*FooMemberFunc)(int x);

int main(void)
{
    Foo bar;
    FooMemberFunc ptr = &Foo::function;

    cout << (bar.*ptr)(4) << endl;
    return 0;
}
The [] operator can be used to give you array-like access (totally convoluted example)

Code: Select all

#include <iostream>

class List {
    static const int size = 3;
    int elements[size];
    int dummy;
public:
    List() 
        {
            for (auto &element : elements)
                element = 0;
            dummy = -99;
        }
    // Array access, any index outside the valid range will affect the dummy
    int &operator[](int el) {
        if (el >= 0 && el < size)
            return elements[el];
        else
            return dummy;
    }
};

int main(void)
{
    List list;
    list[1] = 4;
    list[-5] = 10; // Any index outside 0..2 sets/gets the dummy value
    for (int x = -1; x < 5; x++)
        std::cout << "list[" << x << "] = " << list[x] << std::endl;
    return 0;
}
Similarly operator() allows access via multiple parameters (so you could do the above with multi-dimensional access using list(1,2) = 4; to set list.element[1][2].
operator-> lets you define a function that returns a pointer to another object (which will then have -> applied)

Code: Select all

object->var;
becomes

Code: Select all

(object.operator->())->var;
Similarly operator* (dereferencing) can be overloaded, these two are typically use in making smart pointer types.

alignof was introduced in C++11, it returns the byte alignment a type needs

Code: Select all

cout << "char needs alignment of " << alignof(char) << endl
     << "pointer_to_char needs alignment of " << alignof(char*) << endl;
typeid lets you get the type of a variable, it returns a variable of type type_info (must #include <typeinfo> to use)

Code: Select all

#include <iostream>
#include <typeinfo>

int main(void)
{
    int x;
    long y, z;

    std::cout << "types of x and y are " << (typeid(x) == typeid(y) ? "the same" : "different" << std::endl;
    std::cout << "types of y and z are " << (typeid(y) == typeid(z) ? "the same" : "different" << std::endl;
    return 0;
}
The casts are all used to cast in different ways, static_cast inserts basic type conversions at compile-time, dynamic_cast is similar but is used for changing pointers and references at run-time, const_cast lets you change the const property, and reinterpret_cast is similar to a static_cast but won't emit any code to do type conversions. So a C cast done in C++ would be the same as a static_cast falling back to a reinterpret_cast if static_cast isn't valid (and also a const_cast if needs be). static_cast can change a float into an int but not a pointer into an int whereas reinterpret_cast can change a pointer into an int (providing an int is big enough to hold a pointer) but not a float into an int.
Interesting and new information. Thank you much.

Though I did not know that standard C casts were leagle in C++. I thought there was some weardness about the use of parens being different (can not example as brain not finishing the C++ side at this time).

I now know that there is nothing of reasonable use for me in C++11.

I also know that a few things I would use have changed :( .

And I know that there are a few more operators to overload than I had thought.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 5:23 am

DavidS wrote:Ok something that has changed. Been a long time since I did the test of printing the result of comparisons, though it used to be -1 (makes more since on the CPU level of operating also).
C operators have always returned 1 for logical true. It doesn't make any difference for the CPU, it still has to assign a value whether that value is 1 or -1.
She who travels light — forgot something.

ejolson
Posts: 3072
Joined: Tue Mar 18, 2014 11:47 am

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 6:22 am

Paeryn wrote:It doesn't make any difference for the CPU, it still has to assign a value whether that value is 1 or -1.
The difference between 1 and 0 is one bit. The difference between -1 and 0 on a twos-complement 32-bit machine is 32 bits. Compare flipping one bit on and of with flipping all 32 bits on and off. Which will take more energy and which will generate more electrical noise?

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 6:22 am

DavidS wrote:I now know that there is nothing of reasonable use for me in C++11.
They aren't C++11 (they came in a long time ago, they were codified in C++98, which was, IIRC, the first ISO standard, and at least const_cast, static_cast and dynamic_cast appear in my old and dog-eared copy of Stroustroup from <mumbledy>), but the additional safety given by the cast operators is worth the price of entry alone.

If your compiler doesn't have those, it's a pretty fair guess it doesn't have an implementation of the STL either? Or exceptions, given that that was what killed CFront. Shame, really, as they are massive safety, performance and productivity boosts, and you can't really be said to be programming C++ without at least the STL.

The stuff that actually came in with C++11, where it really starts to diverge from "C with vtables", would probably make your head explode, never mind C++14 or C++1z (C++17, in development)

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 12:56 pm

ejolson wrote:
Paeryn wrote:It doesn't make any difference for the CPU, it still has to assign a value whether that value is 1 or -1.
The difference between 1 and 0 is one bit. The difference between -1 and 0 on a twos-complement 32-bit machine is 32 bits. Compare flipping one bit on and of with flipping all 32 bits on and off. Which will take more energy and which will generate more electrical noise?
The advantage of using -1 (which does work for true as it is non-zero), is that you can use bitwize instructions with any other value for the logical &&, !, !=, || operators, as it has all bits set. Also I do not know if it was ever standardized what value should be returned for true, though it did not used to be, it was up to the compiler.

Try the printf("%d\n",1==0) and printf("%d\n".1==1) tests with a few compilers (did last night as a result of these statements). Some of them will produce a -1 for true, some will produce a 1 for true, and at least three of them produced a 32767 (which is 0x7FFF = 0b0111111111111111). So there is not a constant for the result of TRUE, it is compiler dependent (unless it is a part of the C11 standard, as most compilers are still only C99 compliant)
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

Heater
Posts: 12692
Joined: Tue Jul 17, 2012 3:02 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 1:08 pm

Highly skilled and professional C++ developers building systems that need to be performant and reliable generally have a lot of serious guidelines for writing C++ in order to prevent their projects becoming an unpredictable, unmaintainable, unreliable mess.

For example the authors of software for the Joint Strike Fighter.

Their coding guidelines are a fascinating read which recommend to any C++ programmer. http://www.stroustrup.com/JSF-AV-rules.pdf I believe much of this was written by Stroustrup himself.

Anyway, I picked out a few choice rules from that guideline for your consideration. They are relevant to the conversation that has been occurring here. I added my own comments in italics. Each rule has a rational in the guideline that you can read if you like,

AV Rule 152
Multiple variable declarations shall not be allowed on the same line.
See DavidS' code we are asked to review here. I like this rule, running stuff together on a line creates an eyesore

AV Rule 153
Unions shall not be used.
See previous comments on this above.

AV Rule 159
Operators ||, &&, and unary & shall not be overloaded.
Pertinent to discussion of overloading above

AV Rule 175
A pointer shall not be compared to NULL or be assigned NULL; use plain 0 instead.
Nuts. This starts to make C++ as stupid as Javascript and it's "falsy" types: "false", "0", "null", "undefined"

AV Rule 189
The goto statement shall not be used.
Naturally, that is the road to spaghetti code :)

AV Rule 190
The continue statement shall not be used.
Of course. It's just another form of goto.

AV Rule 191
The break statement shall not be used (except to terminate the cases of a switch statement).
Of course. It's just another form of goto.

AV Rule 208
C++ exceptions shall not be used (i.e. throw, catch and try shall not be used.)
This one is for tufty :). Of course. Exceptions are just another form of goto.

AV Rule 209
The basic types of int, short, long, float and double shall not be used, but specific-length
equivalents should be typedef’d accordingly for each compiler, and these type names used in
the code.
See somewhere above I think.

I just wish there were a compiler switch to enforce rules like this.

@tufty,

I can't buy the idea that one is not using C++ if one is not using the STL. I like to make a distinction between the language and the libraries. Even if the libraries are defined as part of the language standard.

Plenty of programmers are building embedded and real-time systems where the STL is not appropriate or perhaps does not even fit. They are making great use of a lot of C++ features anyway.

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 1:49 pm

DavidS wrote:The advantage of using -1 (which does work for true as it is non-zero), is that you can use bitwize instructions with any other value for the logical &&, !, !=, || operators, as it has all bits set. Also I do not know if it was ever standardized what value should be returned for true, though it did not used to be, it was up to the compiler.

Try the printf("%d\n",1==0) and printf("%d\n".1==1) tests with a few compilers (did last night as a result of these statements). Some of them will produce a -1 for true, some will produce a 1 for true, and at least three of them produced a 32767 (which is 0x7FFF = 0b0111111111111111). So there is not a constant for the result of TRUE, it is compiler dependent (unless it is a part of the C11 standard, as most compilers are still only C99 compliant)
Going back to The C Programming Language (1st edition)
The unary negation operator ! converts a non-zero operand into 0, and a zero operand into 1.
Then later on (I only just found it - it's written differently and in a different place in the ANSI edition)
Another useful form of automatic type conversion is that the relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true and 0 if false.
That's pretty much the definitive book for C from 1978 written by K&R themselves, so those compilers returning -1 or 32767 were/are non-compliant to even K&R C.
She who travels light — forgot something.

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 1:57 pm

AV Rule 190
The continue statement shall not be used.
Of course. It's just another form of goto.

AV Rule 191
The break statement shall not be used (except to terminate the cases of a switch statement).
Of course. It's just another form of goto.
They are a forwards only jump to a language defined location.
Much safer than a goto.
If they avoid using multiple boolean's to control logic (a disaster) even better.
And why have a special case for break in a switch - its either bad or it isn't.
AV Rule 209
The basic types of int, short, long, float and double shall not be used, but specific-length
equivalents should be typedef’d accordingly for each compiler, and these type names used in
the code.
I agree with this one. But I didn't know there were fixed sizes for the floating point types. Double is always 64-bits on modern hardware.
Sometimes its useful to use long and exploit the fact that it changes size.

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 2:04 pm

Heater wrote:Highly skilled and professional C++ developers building systems that need to be performant and reliable generally have a lot of serious guidelines for writing C++ in order to prevent their projects becoming an unpredictable, unmaintainable, unreliable mess.
I'm of the firm belief that "coding standards" are written by failed programmers !

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

Heater
Posts: 12692
Joined: Tue Jul 17, 2012 3:02 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 2:27 pm

jahboater,

Yes, break and continue don't allow quite the same mess as goto. So I'd say they were a tiny bit safer.

My feeling is that if one has dug such a nested hole that you need break, continue or a bunch of boolean flags in order to get out then it's probably time to rethink ones whole approach.

I think I agree about "break" in "switch" statements. But then I always thought the whole switch/case/break syntax was an ugly error prone mess anyway.
I'm of the firm belief that "coding standards" are written by failed programmers !
Ha, yes!

But perhaps they are the best people to write such standards. They know better than anyone what mistakes can be made :)
Last edited by Heater on Mon Nov 21, 2016 3:03 pm, edited 1 time in total.

User avatar
jojopi
Posts: 3078
Joined: Tue Oct 11, 2011 8:38 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 3:01 pm

DavidS wrote:Some of them will produce a -1 for true, some will produce a 1 for true, and at least three of them produced a 32767 (which is 0x7FFF = 0b0111111111111111). So there is not a constant for the result of TRUE, it is compiler dependent (unless it is a part of the C11 standard, as most compilers are still only C99 compliant)
Operators that produce truth values have always been required to use 1 for true. That was the case in C89, in K&R1, and even in the B programming language. https://www.bell-labs.com/usr/dmr/www/kbman.html

It is hard to believe that you have more than three compilers that get this wrong. Can you name them?

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

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 3:11 pm

jojopi wrote:It is hard to believe that you have more than three compilers that get this wrong. Can you name them?
I would name them "not C compilers" if they get such fundamental things wrong.

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

RoyLongbottom
Posts: 281
Joined: Fri Apr 12, 2013 9:27 am
Location: Essex, UK
Contact: Website

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 4:13 pm

jahboater wrote:Sorry, I know this thread has moved on to the benefits of 30 year old C++ compilers, but this might be interesting.
ejolson wrote: This either means that the loop is optimal or the library is not. Is 1688 MB/s the correct memory bandwidth for the Pi 3? Roylongbottom claims the Pi 3 has a double-pumped DDR2 memory bus speed of 900 MHz with a bus width of 4 bytes for a theoretical bandwidth of 7200 MB/s.
I think thats (450Mhz * 2) * 4 which is 3600 MB/s.
Sorry, I forgot to correct those RPi 3 RAM speed calculations at:

http://www.roylongbottom.org.uk/Raspber ... m#anchor11

There, an initial run of my MP benchmark RAM performance indicated 4581 MB/second. Then I found the following Wiki article quoting A53 933 MHz dual channel as 14.9 GB/sec.

https://en.wikipedia.org/wiki/ARM_big.LITTLE

Repeating the benchmark for the following, I noted wide variations, often half those quoted speeds. Then, I remembered that there was a folder with a revised version. The benchmark is read only, with all threads starting at the beginning in the original version, This was no problem until shared L2 or L3 caches became available. The revised version staggers the starting point.

http://www.roylongbottom.org.uk/Raspber ... tm#anchor9

This indicates RPI 3 RAM speed as 2080 MB/sec using 1 thread up to 2383 MB/sec using 4 threads, but somewhat less with the new OpenGL GLUT driver enabled. Another test, running four separate programs simultaneously, indicated similar total throughput.

On the question of old compilers, some might be interested in the following, regarding the efficiency of compilers (and interpreters) for PCs from 1979 to 2013:

http://www.roylongbottom.org.uk/whetstone.htm#anchorPC3

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 5:19 pm

Heater wrote:AV Rule 208
C++ exceptions shall not be used (i.e. throw, catch and try shall not be used.)
This one is for tufty :). Of course. Exceptions are just another form of goto.
The reasons for that probably aren't about flow control, but rather about fear of the performance hit (despite that it usually only manifests itself on the exceptional path), and perhaps binary size. Not being allowed to use exceptions means a shedload of horrible boilerplate error handling code, which is usually more buggy than the code it's trying to "protect".

The main problem with exceptions, though, is the horrible mix of cases they are used for. Some examples :

- a network packet is lost
- a network or resource is totally unreachable before it's needed
- a network or resource disappears whilst in use.
- a bug in the program

Far better to set up rules stating in which circumstances you are allowed use exceptions, and in which you should fail hard. You should never use exceptions to cover unexpected program behaviour (bugs).

Heater
Posts: 12692
Joined: Tue Jul 17, 2012 3:02 pm

Re: Solution to X-Toolkit and portability.

Mon Nov 21, 2016 6:31 pm

tufty,

I'm not inclined to rag on exceptions, or any language feature, because it slows things down a bit or uses a bit more memory. At least as far as creating typical desktop apps and such.
Not being allowed to use exceptions means a shedload of horrible boilerplate error handling code, which is usually more buggy than the code it's trying to "protect".
This perhaps is the problem. Just there you are conflating "error" handling and "exceptions". They are not the same thing.

Errors are things that can be expected to happen. For example the user tries to read a file that does not exist. Ones code can be expected to handle that gracefully and tell the user "No". This error handling code requires a shed load of code. There is no way around it.

Exceptions are what they say they are, exceptional circumstances that you have no idea how to handle in advance. Like running out of memory for example. Or a bug in the code as you say.

Perhaps I have a philosophical view on this but if you are writing some real-time, embedded, possibly safety critical system, or even server software that is expected to run forever. Then if anything exceptional happens, i.e. you did not anticipate it in advance, then it's better to just commit suicide and abort immediately rather than try and continue in an indeterminate state.

That perhaps is why exceptions are off the table for the Joint Strike Fighter.
The main problem with exceptions, though, is the horrible mix of cases they are used for. Some examples :
Yes, I think you are saying what I said above. Exceptions end up getting used for handling normal everyday error conditions. Thus making flow control impossible to comprehend.

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Tue Nov 22, 2016 2:56 pm

Heater wrote:Highly skilled and professional C++ developers building systems that need to be performant and reliable generally have a lot of serious guidelines for writing C++ in order to prevent their projects becoming an unpredictable, unmaintainable, unreliable mess.

For example the authors of software for the Joint Strike Fighter.

Their coding guidelines are a fascinating read which recommend to any C++ programmer. http://www.stroustrup.com/JSF-AV-rules.pdf I believe much of this was written by Stroustrup himself.

Anyway, I picked out a few choice rules from that guideline for your consideration. They are relevant to the conversation that has been occurring here. I added my own comments in italics. Each rule has a rational in the guideline that you can read if you like,

AV Rule 152
Multiple variable declarations shall not be allowed on the same line.
See DavidS' code we are asked to review here. I like this rule, running stuff together on a line creates an eyesore
:)

Ah, so one thing I had been badgered about is something I used to have correct!

So I will very very gladly go back to using one line per veriable declaration, thank you for that (with the exception of the likes of x0,y0 declarations that very clearly belong together).
AV Rule 153
Unions shall not be used.
See previous comments on this above.
In general I agree with that.

With the exception of when doing things like system calls that require a single block of data whose structure can change depending on the return from the call. For example when calling Wimp_Poll in RISC OS, or many of the AES calls in GEM. There is not a more readable way to do this than unions, it can be done with void *, that are assigned to the typed pointers later, though that can also be a mess.
AV Rule 159
Operators ||, &&, and unary & shall not be overloaded.
Pertinent to discussion of overloading above
[/code]

I have just decided that I am not going to talk about C++ at all, I almost never use it anyway.

Code: Select all

[b]AV Rule 175[/b]
A pointer shall not be compared to NULL or be assigned NULL; use plain 0 instead. 
[i]Nuts. This starts to make C++ as stupid as Javascript and it's "falsy" types: "false", "0", "null", "undefined" [/i]
[/quote]

Now that is a very good one, that I strongly agree with.

[quote]
[b]AV Rule 189[/b]
The goto statement shall not be used. 
[i]Naturally, that is the road to spaghetti code :)[/i]
[/quote]

True, and agreed with 100%.

[quote]
[b]AV Rule 190[/b]
The continue statement shall not be used. 
[i]Of course. It's just another form of goto.[/i]

[b]AV Rule 191[/b]
The break statement shall not be used (except to terminate the cases of a switch statement). 
[i]Of course. It's just another form of goto.[/i]
[/quote]

An advantage of ARM BASIC, there is a lot less use of the things like goto, as there is never a good use for them, everything can be done much easier without them.

[quote]
[b]AV Rule 208[/b]
C++ exceptions shall not be used (i.e. throw, catch and try shall not be used.) 
[i]This one is for tufty :). Of course. Exceptions are just another form of goto.[/i]

[b]AV Rule 209[/b]
The basic types of int, short, long, float and double shall not be used, but specific-length
equivalents should be typedef’d accordingly for each compiler, and these type names used in
the code.
[i]See somewhere above I think.[/i]
[/quote]

That I agree with, and is something I used to get in trouble for doing.

I used to define the types INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT32, FLOAT64, and FLOAT80 and got in a good bit of trouble for it, being told that it makes for unreadable code.

[quote]
I just wish there were a compiler switch to enforce rules like this.

@tufty,

I can't buy the idea that one is not using C++ if one is not using the STL. I like to make a distinction between the language and the libraries. Even if the libraries are defined as part of the language standard. 

Plenty of programmers are building embedded and real-time systems where the STL is not appropriate or perhaps does not even fit. They are making great use of a lot of C++ features anyway.[/quote]
I agree on the issue of STL.   Of course I do not like C++ templates, and C++ was a very good language before they added templates.

[b]Also Heater, on the issue of safty of on server data:[/b]
Maybe slightly off topic, though it is one we have debated many times before.

I posted a thread asking for peer review of how to be sure code is readable.  This was on these forums, explicitly in "Other Languages".

That thread vanished from existence, with out a trace.    So much for reliability of server side data.

And that is an important one to me, as I am intending to release software that I want others to be able to easily read and modify.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Solution to X-Toolkit and portability.

Tue Nov 22, 2016 5:04 pm

DavidS wrote:Also Heater, on the issue of safty of on server data:
Maybe slightly off topic, though it is one we have debated many times before.

I posted a thread asking for peer review of how to be sure code is readable. This was on these forums, explicitly in "Other Languages".

That thread vanished from existence, with out a trace. So much for reliability of server side data.
You don't think you could have forgotten where you posted, by any chance?

search.php?keywords=peer+review+readabi ... mit=Search

ejolson
Posts: 3072
Joined: Tue Mar 18, 2014 11:47 am

Re: Solution to X-Toolkit and portability.

Tue Nov 22, 2016 6:10 pm

Heater wrote:For example the authors of software for the Joint Strike Fighter.

Their coding guidelines are a fascinating read which recommend to any C++ programmer. http://www.stroustrup.com/JSF-AV-rules.pdf I believe much of this was written by Stroustrup himself.
While fascinating, if there were not a near infinite amount of good money available to thow after bad, the multiple delays to the F-35 caused by software and other issues would likely lead to the whole project being cancelled. Many corporate software projects fail in ways that seriously impact the future of the company. Along those lines, it is probably good that the foundation stopped funding the Epiphany and the Wayland projects for the Pi. While C++ is advertised as suitable for large software projects, it feels like a grab bag of experimental features cobbled together by tinkerers to me. Creating a document consisting of 100's of rules can't replace using reasonable tools and hiring programmers with common sense who use reasonable tools reasonably. Such a document might even make things worse.

User avatar
DavidS
Posts: 4247
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Solution to X-Toolkit and portability.

Tue Nov 22, 2016 6:54 pm

tufty wrote:
DavidS wrote:Also Heater, on the issue of safty of on server data:
Maybe slightly off topic, though it is one we have debated many times before.

I posted a thread asking for peer review of how to be sure code is readable. This was on these forums, explicitly in "Other Languages".

That thread vanished from existence, with out a trace. So much for reliability of server side data.
You don't think you could have forgotten where you posted, by any chance?

search.php?keywords=peer+review+readabi ... mit=Search
I have no idea how it got moved, though they did not tell me when they did.

I know where I posted it.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

Heater
Posts: 12692
Joined: Tue Jul 17, 2012 3:02 pm

Re: Solution to X-Toolkit and portability.

Tue Nov 22, 2016 9:42 pm

ejolson,

From the outside it looks like the F-35 project has bitten off more than it can chew, not just from a software perspective.

Certainly big corporate software projects have been failing for decades. See Multics and Fred Brook's famous book "The Mythical Man Month". Heck I have worked on many a cancelled project. We never learn.

No idea about Epiphany. The Wayland developers maintain they are trying to remove cruft and shrink what was X11. I don't know.

C++ does indeed feel like a "grab bag of experimental features cobbled together by tinkerers". Reality is though that the C++ devs, the guys on the standards committee, are not tinkerers. They are seriously smart, experienced, guys from MS, Google, Apple, elsewhere.

Somehow the product of a bunch of really smart guys can come out looking like the product of a mad man. How does that happen? See the history of CORBA or XML or HTML/CSS for a similar examples.

The question you raise then is: What are reasonable tools?

Used to be Coral 66, mandated in the UK for military and government projects.

That got scrapped for Ada. As mandated by the DoD in the USA.

Now it's the turn of C++...

What do you suggest?

Aside: Personally, having worked though the Coral 66 (Military radar) and Ada (Boeing 777) thing. I was amazed and somewhat horrified when I heard they were using C++ for the F-35.

Return to “Other programming languages”