Tag: clang

Interesting gcc/clang extensions to C

Interesting gcc/clang extensions to C

C ExampleBoth gcc and clang support extensions to C and while i normally try and make things I write about work on Windows (i.e. Visual Studio), these are useful enough that I thought they deserve a mention. Yes I know you can run gcc/clang on Windows using Cygwin or MinGW, but for various reasons I prefer Visual Studio.

You can add a constructor and destructor functions to a C program; the constructor function runs before main() and the destructor after main().

The syntax is not exactly clean or obvious (those are double underscores before and after the word attribute like Python dunders!) but I got this program to compile/run with clang 10 on Ubuntu as the screenshot shows.  Here’s a listing. I called the two functions ctor and dtor but you can use anything.

#include <stdio.h>

__attribute__((constructor)) void ctor(void)
{
  printf("Constructor runs first\n");
}

__attribute__((destructor)) void dtor(void)
{
  printf("Destructor runs last\n");
}

int main() {
    printf("Main\n");
}

The output  is:

david@DavidPC:~/Projects/Examples$ ./ex1
Constructor runs first
Main
Destructor runs last
Back on the Raspberry Pi

Back on the Raspberry Pi

Pi Asteroids DevelopmentIt has been a few months since I last used it and as you’d expect, it took a little bit of time and effort to get things back to what they were.

I’m pretty good about backing things up and it took about 30 minutes to burn a new SD Card, update it, install VS Code and the C/C++ extension, then copy my asteroids version over. I use WinSCP so had to enable SSH on the PI. It’s disabled by default but just tick a checkbox on the interface tab of the Preferences->Configuration menu.

Even then it didn’t compile. Of course I had to reinstall the dev versions of SDL, SDL_image, SDL_mixer and SDL_ttf and the clang compiler. Still it didn’t compile. I had created a Projects folder and created an Asteroids folder underneath that. I also had the Vs Code JSON files that you need for compiling C/C++. the main one of which is tasks.json. Those were in a folder .vscode which I had backed up but I’d copied it over into the wrong location. You want it located inside your VS Code folder.

This makes sense. If you have say five different projects then you are going to have a different build, link stuff per project. So you’ll have a unique .vscode in each folder. When you want to switch projects, you just close the Folder in the VS Code File menu and open it in the folder for the project that you next want to work on.

Mind you it still wouldn’t compile. It turned out my tasks.json has clang-6 in it. When I did a clang –version on it, it told me it was clang 7.0.1. So I upped it to clang-7 in tasks.json and that fixed it. It all compiled and ran.

Once you’ve done this a time or two it becomes 2nd nature but I can understand novices frustration; there are a lot of moving parts that all have to be right before you can even write and run C code. It’s not like other programming languages are really any better though. If you have setup virtual environments in Python and installed Python modules, you’ll know what it can be like.

 

Fun with Raspberry Pi 4

Fun with Raspberry Pi 4

Bugs!
Image by Ron van den Berg from Pixabay

So it turned up and I setup things up similar to the 3B+. My interest was in seeing what frame rate it can manage compared to the 27 FPS that the 3B+ managed.

When I eventually got Clang, VS Code etc. installed and setup, compiled etc. it crashed just like it did on the 3B+ when first run. And again it failed to load the am2.msk file; I will really have to figure out what’s going on there. But also it would now not load the a1.png image. This is the one with the 24 x 280 x 280 asteroid images.

SDL provides a function SDL_GetError so I added that to the output when an image file fails to load. The error message that came back was Texture dimensions are limited to 4096×4096. Now this is weird for this Pi has 4 GB of RAM (the 3B+ has 1GB) and is outputting on the same 24″ monitor that the 3B+ used as well. Now it’s true that the a1.png file has dimensions of 6,720 x 64, so I can understand why that would cause grief but not why it worked on the 3B+. I suspect it has to do with RAM being allocated between the GPU and CPU so I’ll check that out.

I also installed Clang-6.0 to try that. On the Pi, installing clang defaults to Clang-7 (they changed the name so it no longer has a .0 on the end!). The release notes for Clang-7 suggested a possibility to do with abi incompatibility between Clang-7 and earlier versions. Bit of a longshot but I thought, that might explain the fail to load am2.msk file but no joy.

Well there’s nothing like juicy tender bugs to get my teeth into… the battle is on.

Comparing MSVC vs Clang

Comparing MSVC vs Clang

Listing of some C codeI originally created Asteroids for Windows using Visual Studio 2017 Community Edition. Since then I’ve started the Clang version on Ubuntu and there haven’t been too many differences but there are just a few so in this post I’ll list what I’ve found so far.

Include Paths

On Windows, I was able to get away with #include <SDL.h> but on Linux, I’ve had to include the path so it’s #include <SDL2/SDL.h>. This was probably because I included the full path in the MSVC configuration.

Link Failures

The asteroids.c code in chapter 29 uses sin and cos for the first time and the linker was unhappy with that. So in tasks.json, I’ve explicitly had to add it into args, along with SDL2 and SDL2_image,

            "args": [
                "-g",
                "${file}","${workspaceFolder}/Asteroids/hr_time.c",
                "-o",
                "${fileDirname}/asteroids",                
                "-lSDL2",
                "-lSDL2_image",
                "-lm"
            ],

That “-lm” does that for maths.

Safe functions

Microsoft has its own set of safe functions many with an _s and extra length parameter.

On Linux, there don’t seem to be so many.

So sprintf_s on Windows becomes snprintf.

fopen_s just becomes standard fopen

linux/time.h

As well as time.h in the includes, I needed to add linux/time.h as well.