Category: Source code

1566 Compile errors with just two characters!

1566 Compile errors with just two characters!

1500 compile errorsWhen programmers have to explain why it took longer to get something working,you don’t often here reasons like this. A simple syntax error error took me an hour to find and fix. Yet it does happen and it happened to me today.

Oh sure you feel silly afterwards and it was only a 131 lines of C code. The very last of the 1566 compile errors was unexpected end-of-file found on line 132. That was a red herring of sorts. The error actually occurred right at the start of the program.

Here’s the first 10 lines. It should be quite easy to spot but when you are looking through 130 lines with a hint that it’s messed up the end of the file, it’s not so obvious.

// tictactoe.c
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>

int playerIsX, computerFirst, x, y, danger, turn;
char board[3][3];  // holds X, O and space
char playerPiece, computerPiece;

In case you haven’t spotted it, it’s the missing .h; it should be string.h not string in that 3rd #include. An obvious-in-hindsight clue is the error listing. The files that are mentioned don’t have .h on them.  (cctype, cstdint etc. Those are C++ files and string is a C++ header file. Also mention of namespace in the error message is also a big hint.

Still I think that sets a record for the most errors generated in a C compile! The compiler btw was Visual Studio 2019’s C/C++ compiler.

A useful function to know- atexit

A useful function to know- atexit

Warning signs
Image by Annalise Batista from Pixabay

This is in C, but applies to C++ as well and is part of stdlib. Perhaps you’ve written a program and when it exits, you want it run some final code. The typical use case for this is releasing resources such as memory allocations and closing files. If you are doing networking then it might also be closing network handles.

Then you need atexit(). You pass in the name of void function. When it finishes, it jumps to that function and runs it. Here’s some code to show it in use.

void ExitFunction(void) {
    printf("Exited");
}    

int atv = atexit(ExitFunction);

As good programming practice, you should check that value to make sure it’s 0. If it isn’t then your exit handler failed to register. I’m not sure what would cause that (overzealous antivirus software?)

You might notice that the ExitFunction has a (void) parameter rather than (). The two are the same but atexit() has been told to expect void parameters and will be disappointed should you fail to comply. Not disappointed enough to give you an error but you will incur a warning and you know how I hate to see those.

The reason why I hate warnings is that not all warnings are equal. This one is trivial and could be ignored, but others aren’t and really need dealing with. So I go for zero tolerance to warnings. Some compilers like gcc have a setting to tell the compiler to treat all warnings as errors.

More on generating random numbers

More on generating random numbers

Two dice
Image by Clker-Free-Vector-Images from Pixabay

The very first program I wrote in any programming language was sometime in October 1976. It was in BASIC and it had this line or something very similar. Even then I was into random numbers. I know, uppercase!

LET DIEROLL = RANDOM(6)+1

I’ve been writing small utility that I’ll publish in a few days. It’s 100% in C and I decided instead of using srand(time(null)) for generating random numbers, I’d use something with a bit more oomph. That something is a library called sodium. Using it for just generating random numbers is a bit overkill. But it has the benefit that the random numbers are good enough random to be used in cryptographic code. Not all random number generators are good enough. This one is.

And it’s easy enough and adds just one dll, or you can compile it statically. I’ll do that once I figure it exactly which Visual Studio settings to change.

It takes just one include –

#include <sodium.h>

Then one call to initialise it.

 int i = sodium_init();
 if (i<0 ) {
   error("Unable to initialise sodium library. Error = ",inttoa(i) );
 }

After that you can call one of several functions. Here’s an example from my code. It fills a 64 byte key with the numbers 0-63 but shuffled like cards.


    typedef char key[64];
    key _key;
    uint32_t ival;
    int i,index1,index2;
    for (i = 0; i < 63; i++) {
        _key[i] = i;
    }
    for (i = 0; i < 1000; i++) {
        do {
            index1 = randombytes_uniform(64);
            index2 = randombytes_uniform(64);
        } while (index1 == index2);
        ival = _key[index2]; // swap two indices
        _key[index2] = _key[index1];
        _key[index1] = ival;
    }

The do loop (how often do you actually see those used in code!) generates two indexes in the range 0-63, making sure that they are not the same. It then swaps the two values at those indexes, and does this 1,000 times. It’s very similar to card deck shuffling code.

Do you know how long it would take you to work through all the combinations of 64 numbers this way? IF you could do a million a second, it would take you 1.27×1083 seconds or 4.02×1075 years! Or to make it more meaningful it’s this large! 4.02,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000. That’s approaching (but still far far off) the time for the heat death of the universe which is estimated at 10100!

A small C++ Tip. Return values from Constructors

A small C++ Tip. Return values from Constructors

C++ LogoYou can’t return anything from a constructor.  One way is to use exceptions but those can bring their own issues. Google’s C++ guidelines actually stipulate no exceptions and I’ve heard it from others as well that they prefer not to use them. Some people avoid it by having a mostly empty constructor and then an init() method to do the real initialisation and return a success/fail state.

But there is a simple trick that you can use, just return the state as a reference. Here’s an example. If you want to return more values, use a struct.

#include <iostream>
using namespace std;

class Simple {
public:

    Simple(bool& failure) {
        failure = true;
    }

    ~Simple() {
    }
};

int main() {

    bool fail_flag = false;
    Simple f(fail_flag);
    if (fail_flag)
        cout << "failed " << endl;
    else
        cout << "Success" << endl;
}
Here’s the Raspberry Pi temperature code

Here’s the Raspberry Pi temperature code

To add temperature to the frame caption, I first do a check to see that it is running on a Raspberry Pi. This function does that.

void SetPiFlag() {
	struct utsname buffer;
	tempFlag = 0;
    if (uname(&buffer) != 0) return;
    if (strcmp(buffer.nodename,"raspberrypi") !=0) return;
	if (strcmp(buffer.machine,"armv7l") != 0) return;
	piFlag=1;
}

Note you have to add this include

#include <sys/utsname.h>

Now you need to call this function to return the temperature as a float.

float ReadPiTemperature() {
    char buffer[10]; 
	char * end; 
	if (!piFlag) return 0.0f;
	if (SDL_GetTicks() - tempCount < 1000) {	
		return lastTemp;
	}
	tempCount = SDL_GetTicks() ;
	FILE * temp = fopen("/sys/class/thermal/thermal_zone0/temp","rt"); 
	int numread = fread(buffer,10,1,temp); 
	fclose(temp); 
	lastTemp = strtol(buffer,&end,10)/1000.0f;
	return lastTemp;
}

Things to notice.

  1. If it’s not running on a Pi it always returns 0.0C.
  2. No matter how often it’s called, it only reads the temperature once a second.
  3. In between reads it caches the temperature in a variable lastTemp

When I first wrote this, it was reading the temperature on every frame. It actually changes that quickly but that made it hard to read. So once a second is fine.

I’ve started on the C++ Windows eBook

I’ve started on the C++ Windows eBook

C++ Code listing photoI made the mistake of starting by trying to convert the final version of Asteroid; all 2,200 lines of C into C++.

It got very messy because I was trying to have all the moving objects (Player ship, asteroids, bullets, aliens ship) all based on a common ancestor class but then was trying to manipulate those instances of the ancestor class and downcast back from the ancestor instances and I don’t think you can in C++. Compiler errors galore!

It was the wrong approach and I wasn’t using virtual functions. So instead I’m doing it step by step, adding on new features. Much like the original C development in 13 different steps.

Here’s the slightly shorter asteroids.cpp:

// Asteroids C++ 2020 Chapter 27
#include "game.h"

int main(int argc,char * args[])
{
	Game g;
	g.InitSetup();
	g.GameLoop();
	g.FinishOff();
    return 0;
} 

There are other classes used from Game. I haven’t put everything in one “God” class!

How to read a Raspberry PI temperature in C code

How to read a Raspberry PI temperature in C code

Raspberry PiReading the temperature of a Raspberry PI can be done in a couple of ways. This command:

vcgencmd measure_temp

Outputs something like temp=32.7’C. My 3B+ PI has heatsinks and a cooling fan so runs cool. Even with asteroids it only peaked at 50.5C. Well below the throtle back temperature of 85C.

Another way (I suspect they are the same) is to do

cat /sys/class/thermal/thermal_zone0/temp

Which outputs values like 32705. Just divide by 1000 to get the temperature in Celsius.

But how do we do it in code? Well I’ve tested this code below and it seems to work.

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main(void) {
  char buffer[10];
  char * end;
  FILE * temp = fopen("/sys/class/thermal/thermal_zone0/temp","rt");
  int numread = fread(buffer,10,1,temp);
  fclose(temp);
  printf("Temp = %5.2fC\n",strtol(buffer,&end,10)/1000.0);
}

It reads the device as a string then converts to a long using strtol and divides that by 1000 then prints it. Output is something like:

Temp (C) = 34.88C

Now it just needs combined with the code to detect that it’s running on a Pi and you’re good.

Identifying a Linux system in code

Identifying a Linux system in code

Since I got asteroids running on a Raspberry Pi, I have decided I want to incorporate the temperature in the window caption when you switch it to debug mod by pressing Tab. Currently all that does is display position info on moving objects and bounding boxes.

But if I include that code in, I want to be sure that it only works when running on a Raspberry Pi. So I need some code to identify the system. A bit of digging and I discovered the Linux uname command. That link goes to an online man page for uname.

If I run uname -a on my Ubuntu 18.04LTS I get this.

Linux david-Virtual-Machine 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

And on my PI.

Linux raspberrypi 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l GNU/Linux

In fact the uname -n command gives david-Virtual-Machine on Ubuntu and raspberrypi on the PI. These are the names though names are often changeable and what if someone is running ubuntu on a PI? Yes it is a thing. But the uname -m identifies the CPU.  x86-64 on my Ubuntu and armv71 on the pi.

I did a bit of digging and found a C program on stackoverflow that will do the same as uname.

#include 
#include 
#include 
#include <sys/utsname.h>

int main(void) {

   struct utsname buffer;

   errno = 0;
   if (uname(&buffer) != 0) {
      perror("uname");
      exit(EXIT_FAILURE);
   }

   printf("system name = %s\n", buffer.sysname);
   printf("node name   = %s\n", buffer.nodename);
   printf("release     = %s\n", buffer.release);
   printf("version     = %s\n", buffer.version);
   printf("machine     = %s\n", buffer.machine);

   #ifdef _GNU_SOURCE
      printf("domain name = %s\n", buffer.domainname);
   #endif

   return EXIT_SUCCESS;
}

And this is what it outputs on a PI.


system name = Linux
node name   = raspberrypi
release     = 4.19.97-v7+
version     = #1294 SMP Thu Jan 30 13:15:58 GMT 2020
machine     = armv7l

So that bit is easy to do. Next is getting the temperature, but that’s for another blog entry…

A little trick in Visual Studio Code

A little trick in Visual Studio Code

Matching braces in Visual Stduio CodeIf you have a bit of nesting and you want to make sure your braces match up, Visual Studio code (VSC) can help you with that.

Just drag the cursor over the left or right brace and it will highlight the corresponding brace. In the screenshot you can see the brace on the 2nd line and 5th lines are highlighted.

Here’s a second trick. You can quite easily collapse code blocks. On the left below is uncollapsed code. Now move the cursor between 3 and typedef and a down arrow should appear. Click it and it will collapse the block. It now shows a right arrow and you click it to expand it back.

Before Collapsing a block in C
Collapsed code

Made it to the end of the Linux EBook

Made it to the end of the Linux EBook

Tux with books
Image by OpenClipart-Vectors from Pixabay

That is, I have completed every one of the 13 stages in the game’s development and each is up and running on Ubuntu. It turned out easier than I thought though I still need to fix one or two things.

Because Clang doesn’t support the MSVC fopen_s, I did a quick fix and removed the error checking and when it first ran, it did another segmentation fault because the high score table file didn’t exist. D’oh!

That’s fixed now. Crashing because a file is missing is a very bad practice! Also for some reason last night, Windows and Ubuntu fell out and copy/paste between them wasn’t working. It is working today. I’ve noticed this can be a little bit sensitive at times and I think it was the Windows side that fell over.

However I’ve also been playing with Ubuntu 19.10 and Copy/Paste appears to be disabled on that. That kind of thing I find extremely irritating. I have Guest services ticked, so why does nothing I do enable it? 18.04 LTS apart from last night’s glitch is perfectly happy. And 20.04 Focal Fossa (I know!) is due out on April 23rd.  It’s not quite ready but you can try it an early version if you like. I will be upgrading.