Cuteness of GNU C Extensions for Cats 🐈

Written by Meowing Cat on 6/20/2024, 9:44:00 PM

Make writing C code funnier with GNU C Extensions and make your paws happy! 🐾

Hewwooo, Cat is here again with a new blog post! Today, I’m going to show you some cute GNU C extensions that will make writing C code funnier! 🐾 Cat promises you’ll feel like we are talking about pawing JavaScript code. 🙀

Introduction

Before we start, you might like to know the GCC (GNU Compiler Collection) website. You can find it https://gcc.gnu.org/.


GNU GCC Logo

Sometimes, you think writing C code is boring, right? Writing so much lines of code just to do a simple task can be frustrating and tiring for paws. But, don't worry! Cat is here to show you some cute GNU C extensions that will make writing C code funnier! 🐾

What are GNU C Extensions?

You probably know that C is a simple and low-level programming language. It doesn’t have many features like modern programming languages such as JavaScript, Python, or Rust.

Also, you probably know GCC (GNU Compiler Collection), the most popular C compiler. GCC has some non-standard language features like syntatic-sugars and useful keywords and features that make writing C code funnier and easier.

These non-standard language features are called GNU C Extensions. They are not part of the C standard, but they are supported by GCC and some other compilers.

How to Use GNU C Extensions?

To use GNU C Extensions, you need to define the _GNU_SOURCE macro at the beginning of your C code. This macro tells the compiler to enable GNU C Extensions.

Here is an example:

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    printf("Hello, cute GNU C extensions!\n");

    return 0;
}

Cute GNU C Extensions

Here are some cute GNU C extensions that will make writing C code funnier! 🐱

Blocks

In GNU C, you can’t define a block inside a block. But, with GNU C Extensions, you can define a block inside a block using the { ... } syntax.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    int a = 10;

    {
        int a = 20;

        printf("Inner a: %d\n", a);
    }

    printf("Outer a: %d\n", a);
}

We’ll see this output:

Inner a: 20
Outer a: 10

Normally in C, we would get an error because we defined the a variable twice. But, with GNU C Extensions, we can define a block inside a block and define the a variable again.

This cute feature is very useful when you want to define a variable with the same name in a block without affecting the outer block because finding a unique name for a variable can be hard sometimes. 😸

Statement Expressions

In GNU C, you can’t use a statement as an expression. But, with GNU C Extensions, you can use a statement as an expression using the ({ ... }) syntax.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    int result = ({
        int a = 10;
        int b = 20;

        a + b;
    });

    printf("Result: %d\n", result);

    return 0;
}

Ohhh, you wouldn’t expect the C to be this cute, right? 😻

In this example, we used the ({ ... }) syntax to use a statement as an expression. the code inside the ({ ... }) block will be executed, and the result will be assigned to the result variable.

The ({ ... }) is assigned to a variable right? We could also use it as a function argument, like this:

#define _GNU_SOURCE

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(10, ({
        int a = 10;
        int b = 20;

        a + b;
    }));

    printf("Result: %d\n", result);

    return 0;
}

So, the ({ ... }) block as a whole, is being the result of the logically last statement inside it.

You felt like you were writing JavaScript, right? 😸

Inline Struct Initialization

In GNU C, you can’t initialize a struct inline. But, with GNU C Extensions, you can initialize a struct inline using the { .key = val } syntax.

#define _GNU_SOURCE

#include <stdio.h>

typedef struct {
    int x;
    int y;
} Point;

int main() {
    Point point = {.x = 10, .y = 20};

    printf("Point: (%d, %d)\n", point.x, point.y);

    return 0;
}

Useful, right? 😸

This feature is very useful when you want to initialize and pass an object to a function without defining a variable. You can just pass (Point) {.x = 10, .y = 20} expression on the fly.

For example:

#define _GNU_SOURCE

#include <stdio.h>

typedef struct {
    int x;
    int y;
} Point;

void print_point(Point point) {
    printf("Point: (%d, %d)\n", point.x, point.y);
}

int main() {
    print_point((Point) {.x = 10, .y = 20});

    return 0;
}

Looks like you’re writing JavaScript, right? 😸

Nested Functions

In GNU C, you can’t define functions inside a function. But, with GNU C Extensions, you can define functions inside a function using the ({ ... }) syntax.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    int result = ({
        int add(int a, int b) {
            return a + b;
        }

        add(10, 20);
    });

    printf("Result: %d\n", result);

    return 0;
}

In this example, we defined the add function inside the ({ ... }) block and used it to add two numbers.

I’m sure you’re surprised by how cute C can be! 😻

Typeof

Normally, in C, you can’t get and use the type of a variable in another declaration/definition. But, with GNU C Extensions, you can get the type of a variable using the typeof keyword. This happens in compile-time and ofc it doesn’t add any runtime overhead.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    int number = 10;

    typeof(number) result = number * 2;

    printf("Result: %d\n", result);

    return 0;
}

This feature is very useful when you write some cute and useful macro libraries. 🐾 Again, you felt like you were writing JavaScript, right? 🙀 But… don’t worry all of these things are compile-time. 😇

Labels as Values

In GNU C, you can’t get the address of a label. But, with GNU C Extensions, you can get the address of a label using the && operator.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    void *label = &&my_label;

    goto *label;

my_label:
    printf("Hello, cute GNU C extensions!\n");

    return 0;
}

As you can see, we can get the address of the my_label label using the && operator and use it with the goto statement.

Case Ranges

In GNU C, you can’t use ranges in switch statements. But, with GNU C Extensions, you can use ranges in switch statements using the case ... ... syntax.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    int number = 5;

    switch (number) {
        case 1 ... 5:
            printf("Number is between 1 and 5\n");
            break;
        case 6 ... 10:
            printf("Number is between 6 and 10\n");
            break;
        default:
            printf("Number is out of range\n");
            break;
    }

    return 0;
}

In this example, we used the case 1 ... 5: syntax to check if the number is between 1 and 5.

Local Labels

In GNU C, you can’t define labels inside a block. But, with GNU C Extensions, you can define labels inside a block using the label: syntax.

#define _GNU_SOURCE

#include <stdio.h>

int main() {
    {
        label:
        printf("Hello, cute GNU C extensions!\n");
    }

    goto label;

    return 0;
}

In this example, we defined the label label inside a block and used it with the goto statement.

Non-local Labels

In GNU C, you can’t use a label outside the function where it’s defined. But, with GNU C Extensions, you can use a label outside the function where it’s defined using the __label__ keyword.

#define _GNU_SOURCE

#include <stdio.h>

void my_function() {
    __label__ my_label;

    goto my_label;

my_label:
    printf("Hello, cute GNU C extensions!\n");
}

int main() {
    my_function();

    return 0;
}

In this example, we defined the my_label label inside the my_function function and used it with the goto statement in the main function.

Conclusion

Soo many cute features in C, right? 😻 Today, Cat teached you these cool and cute features; now, you can write cool apps in C funnier. 🐾

I hope you enjoyed this blog post! If you have any questions or suggestions, feel free to leave a comment below. Cat will be happy to help you! 🐱🐈


That’s all for today! I hope you enjoyed this article. If you have any questions or comments, feel free to ask! You can reach me on the GDBFrontend Discord. Cat is always here to help you! 🐈 🐾

Happy code pawing! 🐾