SNCA:C

From Soyjak Wiki, the free ensoyclopedia
(Redirected from C)
Jump to navigationJump to search
A C programmer discovering that pointers bite back

C is a general purpose programming language and one of the oldest and most influential. It is the ancestor language of C++ which in turn influenced C#, Java and Rust; it is very close to the hardware (whatever that means o algo) which is why it's used in software like Linux and DOOM (because Torvalds and Carmack are aryanGODs midwits who hate C++). C does not use a garbage collector (unlike Java, C#, and Python) and all memory must be directly allocated and freed manually by using malloc() and free(). Even though C++ and Rust literally do this for free with no runtime cost by using smart pointers, RAII, and ownership-based memory. Also C is compiled ahead of time rather than interpreted or just-in-time compiled.

Terry Davis created HolyC which is his own dialect of C, which uses 'Just In Time' (JIT) compilation. It also borrows some features from C++.

C is the lingua franca of foreign function interfaces, meaning many languages have bindings to call C functions. For C++, because C++ preserves backwards compatibility with C, this is trivial.

Safety concerns[edit | edit source]

WARNING: WORDSWORDSWORDS
This page or section is just one big wall of text.


As you can see, C pointer syntax is incredibly retarded.

Because C uses direct memory management, you have access to pointers which essentially point to something in memory (in either the stack or the heap).

  • If you don't free() memory on the heap that you malloc()ed you will get a memory leak.
  • After you free() memory, you cannot use whatever was there, as that memory no longer belongs to you; it has been returned to the OS.
  • Calling free() on a pointer twice is illegal. Why? Because that memory might get used elsewhere, and the system doesn't know if you meant to free the first object or the object that might now live in that address.
  • A void* (void pointer) is a pointer that can basically point to any sort of data type. The compiler doesn't know what it points to. You cannot dereference it directly, you must cast it to a specific type.
    • Because C doesn't have generics (you can make _Generic macros but that's a macro and not a function) you cannot write generic code like with C++ templates, you have to store things as void* and then cast them to the actual type. (This is similar to pre-Java 5 which did not have generics, so container types like HashMap stored everything as Object and had to be manually casted down to their actual type.) This is obviously not safe and also probably very inconvenient. (Also C doesn't allow operator overloading so you can't do things like define your own math structs and add them with +, a lot of fags will say operator overloading can be abused but same could be said about literally every other programming feature)
  • If a pointer is null (NULL) and you dereference it you will get a segmentation fault (segfault). (In Java dereferencing null results in a NullPointerException which is like a controlled segfault on the JVM.) Also, a dangling pointer is a pointer that points to memory that has been deallocated, and accessing it is illegal.
    • C23 (the version of C released in 2023) adds nullptr which is a type-safe null pointer constant. Prior to this C used a macro NULL which expanded to (void*)0 which isn't heckin type safe o algo.
  • Using an uninitialized variable is illegal.
  • An integer overflow occurs when a calculation exceeds the maximum/minimum value of an integer.
  • Accessing an index outside the length of an array causes a segmentation fault. Also, there is no native String type in C, there is only char[] (arrays of char) or char* (pointers to string literals).
  • A stack overflow is when the call stack exceeds the allocated size. This can happen when, for example, you allocate too many variables or have a function call itself recursively.
  • A buffer overflow is when you write more data to a buffer than it can hold. A buffer might be an array, string, or some block of memory. This will corrupt memory. It is also used by hackers such as the sharty to perform exploits such as code injections and arbitrary code executions, such as changing the return address to call some other function.
  • Undefined behavior is when you do something that is illegal and therefore not defined by the standard. When that happens there is no guarantee what happens - it is entirely up to compiler implementation. Undefined behavior is allowed by the C standard to allow compilers to make optimizations.

Rust is more aryan than C. People who claim C is more aryan are nocoder trannies who get all their opinions from /g/ and have never written C. A malding tranny wrote this sentence and the list above if that matters.

Example[edit | edit source]

We first define the following header clamp.h:

#pragma once // ensures the header is included only once

#include <stddef.h>
#include <stdint.h>

// Alias float types acording to <stdint.h>
typedef float float32_t;
typedef long float64_t;
typedef long double float128_t;

// Define the bodies for both signed and unsigned type
#define CLAMP_BODY_U(type) \
    type clamp_##type(type val, type min, type max) { \
        return (val < min) ? min : (val > max) ? max: val; \
    } \
    \
    unsigned type clamp_u##type(unsigned type val, unsigned type min, unsigned type max) { \
        return (val < min) ? min : (val > max) ? max: val; \
    }

// Define the body for only the signed type
#define CLAMP_BODY(type) \
    type clamp_##type(type val, type min, type max) { \
        return (val < min) ? min : (val > max) ? max: val; \
    }

/**
 * @brief A generic clamp function.
 * 
 * @param val The value to clamp.
 * @param min The minimum value.
 * @param max The maximum value.
 * @return The value after clamping.
 */
#define clamp(val, min, max) \
    _Generic((val), \
    char: clamp_char, \
    unsigned char: clamp_uchar, \
    int8_t: clamp_int8_t, \
    uint8_t: clamp_uint8_t, \
    int16_t: clamp_int16_t, \
    uint16_t: clamp_uint16_t, \
    int32_t: clamp_int32_t, \
    uint32_t: clamp_uint32_t, \
    int64_t: clamp_int64_t, \
    uint64_t: clamp_uint64_t, \
    float32_t: clamp_float32_t, \
    float64_t: clamp_float64_t \
    float128_t: clamp_float128_t \
    size_t: clamp_size_t \
    ptrdiff_t: clamp_ptrdiff_t
)(val, min, max)

CLAMP_BODY_U(char);
CLAMP_BODY_U(int8_t);
CLAMP_BODY_U(int16_t);
CLAMP_BODY_U(int32_t);
CLAMP_BODY_U(int64_t);
CLAMP_BODY(float32_t);
CLAMP_BODY(float64_t);
CLAMP_BODY(float128_t);
CLAMP_BODY(size_t);
CLAMP_BODY(ptrdiff_t);

Then in main.c:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "clamp.h"

/**
 * @brief Determines whether the tranny should ack based on a given probability.
 *
 * @param ackProbability An (unsigned) integer between 0 and 100 representing the chance of acking.
 * @return True if the random probability is less than the ackProbability; otherwise, False.
 */
bool shouldAck(unsigned int ackProbability) {
    return (rand() % 101) < (float)clamp(ackProbability, 0, 100);
}

/**
 * @brief Main function that decides whether to ack or scream TRANS RIGHTS ARE HUMAN RIGHTS!!!!!!!! based on probability.
 *
 * @param argc The number of command line arguments.
 * @param argv An array of command line arguments.
 * @return Whether the program executed successfully.
 */
int main(int argc, char* argv[]) {
    srand((unsigned int)time(nullptr));
    if (shouldAck(41)) {
        fprintf(stderr, "%s\n", "ACK!!!");
        raise(SIGSEGV);
    } else {
        printf("%s\n", "TRANS RIGHTS ARE HUMAN RIGHTS!!!");
    }
    return 0;
}

Pre-C23 version[edit | edit source]

Before C23, you had to include <stdbool.h> because booleans were not a core primitive type in the language, also there was no nullptr so you had to use NULL.

#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define clamp(val, min, max) (val < min) ? min : (val > max) ? max: val; 

/**
 * @brief Determines whether the tranny should ack based on a given probability.
 *
 * @param ackProbability An (unsigned) integer between 0 and 100 representing the chance of acking.
 * @return True if the random probability is less than the ackProbability; otherwise, False.
 */
bool shouldAck(unsigned int ackProbability) {
    return (rand() % 101) < (float)clamp(ackProbability, 0, 100);
}

/**
 * @brief Main function that decides whether to ack or scream TRANS RIGHTS ARE HUMAN RIGHTS!!!!!!!! based on probability.
 *
 * @param argc The number of command line arguments.
 * @param argv An array of command line arguments.
 * @return Whether the program executed successfully.
 */
int main(int argc, char* argv[]) {
    srand((unsigned int)time(NULL));
    if (shouldAck(41)) {
        fprintf(stderr, "%s\n", "ACK!!!");
        // alternatively: fputs("ACK!!!\n", stderr);
        raise(SIGSEGV);
    } else {
        printf("%s\n", "TRANS RIGHTS ARE HUMAN RIGHTS!!!");
        // alternatively: puts("TRANS RIGHTS ARE HUMAN RIGHTS!!!");
    }
    return 0;
}

Windows version[edit | edit source]

To compile make a nuproject under "Win32 Application" and choose Blank Application. in Visual C++ 6.0, make a Main.c file in the project folder and paste it in then include it in the project, compile it and run it.

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>

#include "clamp.h"

/**
 * @brief Determines whether the tranny should ack based on a given probability.
 *
 * @param ackProbability An (unsigned) integer between 0 and 100 representing the chance of acking.
 * @return True if the random probability is less than the ackProbability; otherwise, False.
 */
bool shouldAck(unsigned int ackProbability) {
    clamp(ackProbability, 0, 100);
    return (rand() % 101) < (float)clamp(ackProbability, 0, 100);
}

/**
 * @brief Main function that decides whether to ack or scream TRANS RIGHTS ARE HUMAN RIGHTS!!!!!!!! based on probability.
 *
 * @param hInstance Handle to the current instance of the application.
 * @param hPrevInstance Handle to the previous instance of the application.
 * @param lpCmdLine Command line arguments passed to the application.
 * @param nCmdShow Specifies how the window is to be shown.
 * @return Whether the program executed successfully.
 */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    char message[256];
    srand((unsigned int)time(nullptr));
    
    if (shouldAck(41)) {
        // Show "ACK!!!" message box
        MessageBox(nullptr, "ACK!!!", "Result", MB_OK | MB_ICONINFORMATION);
	const char* msg = "ACK!!!";
	WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), msg, strlen(msg), NULL, NULL);
    } else {
        // Show "TRANS RIGHTS ARE HUMAN RIGHTS!!!" message box
        MessageBox(nullptr, "TRANS RIGHTS ARE HUMAN RIGHTS!!!", "Result", MB_OK | MB_ICONINFORMATION);
	const char* msg = "TRANS RIGHTS ARE HUMAN RIGHTS!!!";
	WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), msg, strlen(msg), NULL, NULL);
    }

    return 0;
}

Gallery[edit | edit source]

C
is part of a series on
Soyience™

Visit the Soyence portal for more.
"We are all just hecking star dust or something!"
Peer reviewed sources [-+]
Fields of science [-+]
Science in praxis [-+]
Theoretical branches [-+]