Category: C

My ideas for standards in C programs

My ideas for standards in C programs

Follow the rules...
Image by Gerd Altmann from Pixabay

As I’m somewhat restricted at the moment, bashing away on a 7 year old Toshiba laptop running Ubuntu, I thought I’d look around for some C games to help keep the blog going. There’s no shortage of games in C, even those that use SDL2 but what I’ve found is they can be a real pita to compile.

I guess most are for Linux and SDL but I’ve found things like the include path for SDL header files is one pain point. VS Code has a Replace in Files menu item so it’s not too difficult to change paths in multiple files.

Another difference I found was putting inline functions in the middle of a function. I didn’t know you could nest functions that way. A bit of digging found that good old gcc allows this as an extension but it’s definitely not normal C and clang doesn’t allow it which is what I tend to use.

My C standards

So my modest standards for writing C code are, to make life a bit simpler for porting…

  1. Use conditional compilation so you can compile on Windows and Linux. This includes paths to SDL, string print to buffers, MSVC _s functions (on Windows). Please compile on both platforms; it’s real easy to break it!
  2. I’ll eventually use this so that the timer routines I use will be one set of files that can compile on MSVC/clang.
  3. No nested functions. Yes I know gcc can do it, but its just unnatural. Use recursion if you must or function pointers but not nesting. If you really want to nest functions, program in Delphi or C#.

Other things I’d like are mostly taste, like putting a comment for every function.

Things that don’t really matter are whether you put function definitions before main() or after. If you put them after then you have to include a definition.

Likewise I don’t care if you use #pragma once or the older compile guards.

It’s probably a good idea to not call any of the GitHub banned functions. Remember who owns GitHub! (the same people who added the _s functions in Visual C++/MSVC…)

New Tutorial on getting started with SDL

New Tutorial on getting started with SDL

SDL REctanglesI had this tutorial pencilled in to do and it’s now done. It’s the old SDL rectangles program that was part of the eBook. I’ve modernised it a bit so the same file will now compile under either MSVC on Windows or VS Code/Clang on Linux without changes.

I used the _WIN32 predefined macro so it compiles the call to Windows cod on Windows. Here’s an example:

#ifdef _WIN32
		sprintf_s(buff, sizeof(buff), "%10.6f", getElapsedTime(&s));
#else
		snprintf(buff, sizeof(buff),"%10.6f",diff(&s));
#endif

I do a similar thing with the path to SDL which is “SDL.h” on Windows but “SDL2/SDL.h” on Ubuntu. Writing code this way makes it  lot less of a hassle.

The game of 2048 in C in your browser

The game of 2048 in C in your browser

2048 game playing in a browserBack in 2014, an Italian developer called Gabriele Cirulli devised a puzzle game called 2048. It has been implemented on many platforms (I have it on my iPhone) and here is a link to a C version of it (in 300 lines) by developer Nishchith Shetty that plays it in a browser using WebAssembly.

The idea behind the puzzle is that you combine the numbered pieces by moving pieces intro same numbered pieces. 2 into 3, 4 into 4 and so on.

WebAssembly is the technology that lets you run programs in many languages (including C and C++) in your browser at speeds up to 50% of native code.  It’s also used in Blazor where you can write C# programs that run in the browser.

To convert the C code to WebAssembly, you have to install a transpiler (a program that converts one programming language to another) called Emscripten, then it’s a single command line instruction to build the WebAssembly from the C sources and SDL2. Or you can just play it online here.

I’ve been meaning to do a WebAssembly version of my asteroids game using Emscripten. it’s just been sheer laziness that I haven’t got round to it.

 

In praise of Visual Studio

In praise of Visual Studio

Visual Studio debuggingLooking at some of the posts on the C subreddit about recommendations for a text editor to help learn C, I see many people recommending editors like Sublime Text, Notepad (on Windows).

I started programming in an era when IDEs were few and far between and an IDE is a wonderful time saving device. It is vastly superior to editing in a text editor then launching a compiler either by command or a batch file.

With an IDE you get immediate feedback on where the errors are, sometimes with a mini-map that lets you navigate directly to the error. It’s quicker to refactor code (though that’s a function of an editor) and usually one key press away from running or debugging.

Debugging in particular is very good in Visual Studio on Windows or Visual Studio Code on Windows/Linux/Mac. It’s visual, you can see multiple lines of code, add breakpoints and step through it with one key press.

I find line debuggers like GDB to be very frustrating by comparison.  Mousing over a variable and seeing its value in a debugger is a big time saver. Also seeing the stack calls and being able to jump to calls in the stack is handy.

Now if you are used to Linux, working in a terminal and compiling code through batch files then fine, but I believe its a bit of a hurdle for new programmers. An IDE makes it easy to switch from editing, compiling and debugging without leaving the program. It is all round more productive and easier to get into for a beginner.

So it’s worth at least trying out the free version (Community Edition) of Visual Studio if you are on Windows.  The days when Microsoft hated Linux (They called it a cancer!) are long past.  And no I don’t get paid for advocating Visual Studio; I just like it. Considering that it’s completely free, it’s remarkable value.

Simple but effective optimisation in C

Simple but effective optimisation in C

StopwatchHere’s a short program. It repeats a loop twice, indexing through a text string a million times adding up the value. Instead of starting the total at 0, I set it to the outer loop index, to try and reduce the scope for immediate optimisation.

#include<stdio.h>
#include <string.h>
#include "hr_time.h"

stopWatch s;

char* testString = "This is a rather long string just to prove a point";
int main()
{
    int total = 0;
    startTimer(&s);
    for (int i = 0; i < 1000000; i++) {
        total = i;
        for (int index = 0; index < (int)strlen(testString); index++) {
            total += testString[index];
        }
    }
    stopTimer(&s);
    printf("Total =%d Took %8.5f\n", total, getElapsedTime(&s));

    startTimer(&s);
    int len = (int)strlen(testString);
    for (int i = 0; i < 1000000; i++) {
        total = i;
        for (int index = 0; index < len; index++) {
            total += testString[index];
        }
    }
    stopTimer(&s);
    printf("Total =%d Took %8.5f\n",total, getElapsedTime(&s));
    return 0;
}

I compiled and ran it twice, once in Debug and once in Release mode on Windows using MSVC.

Debug:

Total =1004673 Took 0.55710
Total =1004673 Took 0.11465

Release

Total =1004673 Took  0.00762
Total =1004673 Took  0.00765

Clearly in Release compilation, the compiler is smart enough to realise that it can optimise strlen(testString) away so there’s no difference between the two times. But in debug it’s clear that calling strlen() inside a for loop is relatively slow.

I compiled it and ran it with clang on Ubuntu 20.04 in the Hyper-V VM. The times with default optimization were

0.18370 
0.10644

and with “-O3” added to the compile line for maximum optimisation,. this changed to

0.0762
0.0745

which is almost identical to the Windows release compile times.

Portable Life in C

Portable Life in C

apelifeI’ve mentioned Life before, this is the cellular automata as discovered by John Horton Conway. It’s perhaps less of a game and more of a recreation for anyone fascinated by programming. It’s hard to add up how many man-hours have been spent on it.

Developer Justine Tunney (aka Jart on Github) has developed a portable Life called Apelife. Portable as in it can run on Windows (graphically) and Linux (Text User Interface). The application is a modest 112 KB in size and is one of the fastest I’ve seen. When you have a large area and gliders whizz across it, you know its fast.

She is also the author of Cosmopolitan C which Apelife uses.  It lets gcc outputs portable binaries that will run on every Linux distro in addition to Mac OS X, Windows NT, FreeBSD, OpenBSD, and NetBSD. It’s rather ingenious.

 

 

Added a tutorial on memory use in C

Added a tutorial on memory use in C

RAM BoardYou can read the tutorial here. It looks at the different ways memory is used in a C program. Do you know for instance what BSS is and when it is used compared to Data or where variables in a function declared static are held in memory?

I also tried overwriting a text literal out of curiosity to see what happens. Here’s the source:

#include<stdio.h>
#include <string.h>

char* name="My name is David";
int main()
{    
    strcpy_s(name,10, "New name");
    printf("Name = %s\n", name);
    return 0;
}

 
As you’d expect it blew up”

Slay Tutorial four published

Slay Tutorial four published

Debug ModeTutorial four of my reimagining of the game Slay continues.

This was an interesting bit of code to write, particularly setting the player hexagons. Then I tried to do too much in one go, adding the forts at the same time. I split this into separate functions.

It makes extensive use of recursion and that handy trick when you work with hexagons, the IsValidHex() function which tells you which six of the surrounding eight locations are valid. This is needed because the map is stored in a 2d array so in a 3×3 block, the centre location is surrounded by eight locations.

When you use hexagons, it’s more like a brick wall with each alternate row moved over a bit.  Now every location is surrounded by six adjacent locations just like in a hexagon grid. It turns out that a very simple function can tell you which of the 8 surrounding locations are valid.

In the grid I’m using, which runs in rows horizontally either 1,3 or 5,7 cells are invalid depending on whether the row is odd or even.

Here is a normal block of 3 x 3 locations.

7 0 1
6 x 2
5 4 3

But if I slide it over by 2 characters you get this.

  7 0 1     or     7 0 1
 6 x 2               6 x 2
  5 4            5 4 3

So by ignoring the bold locations, you can simulate a hexagon grid.

I’ve also added Debug mode which toggles with the tab key and introduced a blockId to each hex so you can see which hexes are lumped together. In Debug mode, the BlockId is printed out over the hex as in the screenshot. I’ve used the SDL_ttf library to draw the text. It slows down the screen update by a factor of 40x but is just fast enough to do 60 frames per second.

It’s interesting that the Ubuntu code running under Hyper-V is actually a lot faster than the Windows code.  As with previous tutorials, the code includes conditional compilation so it will compile and run under Windows or Linux.

Note, this code is not quite perfect. It now has three bugs:

  1. The map generator occasionally produces a map with a 2nd smaller continent separated by one hex from the main continent.
  2. Toggling Debug mode a lot makes it behave oddly. I thought I’d fixed that but I’m not so sure.
  3. Some blocks of contiguous hexes (all the same colour) lack forts.
Ideas for C Projects when learning it

Ideas for C Projects when learning it

Maze
Image by Gordon Johnson from Pixabay

Personally I always found the best way for me to learn a new language was to take an existing program- maybe something 500 lines or so long and completely convert it to the new language. It forces you to learn how to do things like string and file handling, organising the program, getting input and producing output and so on.

But having seen requests (on the C programming subreddit) for ideas to help someone apply their newly learnt knowledge, here’s a list of ideas of projects that are doable ion C. Nothing silly like database or operating systems!

  1. A simple calendar. Enter a date and show the month. Bonus points if you can use past dates and show the day that a date is on. Hint. Look up Zeller’s Congruence.
  2. Implement John Conway’s Game of Life. A cellular automaton that can be quite fascinating.
  3. Have a go at a Snake Game.  No cheating by looking at the Games Sources (link above on the top menu).
  4. Solve the 8 Queen’s problem. Put 8 queens on a chessboard so no piece can see and attack another.
  5. Create a maze generator. Make sure it includes at least one path from start to finish.

If you get through that lot, you go up a level and should look at this list.

Answer to the C Puzzle

Answer to the C Puzzle

Solution
Image by Gino Crescoli from Pixabay

If you look back at the puzzle, you might think the for loop is a bit odd starting at -1 and that’s the snag. It exits the for loop immediately because -1 is actually more than 5. It’s a rather subtle bug. The type of d is obviously int, but the type of (TOTAL_ELEMENTS – 2) is unsigned int.

So what I believe is happening is the compiler is promoting d to an unsigned int which is 4294967295, and clearly that’s a bit larger than 5. To fix this just put (int) before the (TOTAL_ELEMENTS – 2) in the for loop and it will work.