/tech/ - Technology

Technology & Computing


New Reply
Name
×
Sage
Subject
Message
Files Max 5 files32MB total
Tegaki
Password
[New Reply]


Program_in_C.mp4
[Hide] (6.5MB, 1280x720, 00:51)
Here's how you could "fix", or make a better version of the C programming language.

How would you improve C or another language?

Most important

- #import, imports the file into the program, but only makes the contents (variables, functions, types) available inside files that include it directly. It does not place the contents where you #imported it like #include does. Header files and compiler settings are unnecessary for #imported files. #defines do not have to be compatible with it, if that's what it takes. #include is still useful though, although I would probably call it #paste instead.
- Use . instead of -> for dereferencing struct members. It seems like a nitpick but it's important because of how prevalent and annoying and totally pointless (insert pointer joke) it is.
General

- Built-in build system. Use a more restrictive version of C as a "scripting language" (whatever is required to allow it to compile instantaneously), it compiles into a temporary program that runs inside the compiler, essentially it's only purpose is to set up the compiler settings and some global variables, maybe copy some files around. I'm fine with using a separate build script for personal use, but as soon as I have to interact with someone else's code and build processes, I just want to throw all of computers into the trash. The compiler should only have 1 or 2 options: selecting the build file, and maybe an output path. Build files should be able to inherit other build files (so you can keep most of the settings same, and only change a couple things for different build types).
- Structs are automatically typedef'd. Maybe you can optionally pre-declare it to solve visibility issues (2 structs that contain pointers to each other).
- Types for enums, and type checking (can't set a value from enum 1 into a variable whose type is enum 2, without casting).
- Namespaced enums and automatic member picking. For the enums and function "enum FOO {X, Y, Z}; enum BAR {X, Y, Z}; void fizzle (FOO);", you can call the function with "fizzle(.X)" which has the same meaning as "fizzle(FOO.X)". "X" by itself would not refer to anything unless one of the enums was anonymous.
- Bitfield type. Basically just an enum, except it gives each member a different 1 bit (1, 2, 4, 8, 16...).
- {} automatically casts to the target type where ever possible, no need to cast it manually. Example: for function "void foo (Vec2)", you can just call it with "foo({.x=1})" instead of "foo((Vec2){.x=1})"
- Variables do not implicitly cast if there may be loss of information. For example u8 to u32 works, but u32 to u8 requires manual casting. Same with floats to ints, signed ints to unsigned ints.
- Variables initialize to zero by default unless you say otherwise. For example "Vec2 pos;" is the same as "Vec2 pos = {0};", meanwhile "Vec2 pos = #noinit;" is undefined.
-  works on all types, including structs. "if (foo  bar)" just works, always, as long as the types are same.
- Anonymous structs should just work, and be compatible with each other. For example if you just want to group 2 values, you shouldn't need to declare a type name for it when you send it around.
- Ability to get the member of a struct directly from a return value. For example for the function "Vec2 foo ()", you can do "float x = foo().x". This, when combined with anonymous structs as mentioned above, would allow you to do multiple return values by yourself without explicit language support for it.
- Compile-time functions (constexpr). Basically a it is guaranteed to run at compile-time, so it just leaves behind it's return value and doesn't even exist at runtime.
- Make it easier to get rid of libc or whatever it is that bloats the hell out of your program. Your hello world program should be about 1kb, and if you don't import any libraries then the only thing that should make it bigger is the code that you type in.
- 16-bit floats.
- Switch cases break by default. "fallthrough" keyword added for falling through. "break" does not interact with switch, so you can break from an outer loop with switch.
- More run-time memory safety options, better error reporting, and callstack tracing (especially upon a crash), toggleable with build settings.
- Safe version of alloca, or just make alloca be safe (returns NULL if it fails, instead of silently exploding)
- function_id, basically func except it returns a unique integer ID for the function instead of a string for the name, starts from 1 so 0 can be treated as an error. Also function_count or max_function_id so you can create an array that contains information for every function.
- Inline functions actually inline properly and work properly, there's no reason that a function should ever fail or refuse to inline, unless you explicitly allow "optimizations" to ignore it when you told the compiler to inline the fucking function.
- Better function and variable visibility logic: "local" = local to the current file only (this is the default), "public" = visible to other files through #import, "export" = available outside of the program as dynamic library functions
- _Generic lets you select arbitrary code snippers, not just words, for example "_Generic(x, int:{ foo(x, 0.5) }, default:{ foo(100, x) })"
- Forbid setting variables inside "if" parentheses, it makes code less readable, but more importantly is error-prone. "if (x = foo())" should not be valid, and looks too similar to "if (x == foo())".
- #defines that are local to a function (2 functions with the same #define inside of them won't conflict).
- Multiline macros. For example:
 c
#startmacro(x)
	foo(x);
	x = 14;
#endmacro
- Custom string delimiters with options. Especially options to manipulate whitespaces so you can still tab and space the text block in your source code properly without affecting the string content. For example:
 c
char* foo = #string(ignore_tabs, ignore_leading_whitespace, ignore_trailing_whitespace) #LOL_STRING#
	this is a "story"
	all about how my #1 life
	got turned upside down
#LOL_STRING#;
- #onbreak, similar to a macro, except it's automatically placed directly before all the following scope breaks (at the end of loops and if blocks, before return statements, etc) from the scope where it was defined in.
 c
void foo () {
	for (...) {
		if (e) return; // not placed here because this is before #onbreak
		
		char* foo = malloc(123);
		#onbreak free(foo);
		
		if (x) {
			/* #onbreak contents placed here because of continue */
			continue;
		}
		do_thing();
		if (z) {
			/* #onbreak contents placed here because of return */
			return;
		}
		do_party();
		/* #onbreak contents placed here because the scope where it was defined ends */
	}
}
- A better way to do variable arguments. There's many ways you could handle it but anything is probably better than the half assed crap that C currently does. I would be inclined to use some kind of type IDs because they have the least structural implications, all the language really needs to do is create a list of IDs for all the argument types:
 c
void foo (... arg) {
	void* p = va_datapointer(arg);
	for (int i=0; i<va_count(arg); i++) {
		switch (va_typeid(arg, i)) {
			case typeid(int):   printf("Argument %i is an int: %i\n", i, *p);                           p += sizeof(int);   break;
			case typeid(float): printf("Argument %i is a float: %f\n", i, *p);                          p += sizeof(float); break;
			case typeid(Vec2):  printf("Argument %i is a Vec2: %i %i\n", i, ((Foo*)p)->x ((Foo*)p)->y); p += sizeof(Vec2);  break;
			default:            printf("Argument %i is invalid!\n", i);                                                     return;
		}
	}
}
Vec2 pos = {};
foo(123, 0.5, pos);

// arg is just a pointer, imagine the following (the variables should be tightly packed in memory) (#defines are "insecure" for the sake of clarity):
#define va_count(arg)        *(int*)arg
#define va_datapointer(arg)  arg + sizeof(int) + (*(int*)arg * sizeof(u16))
#define va_typeid(arg, i)    *(u16)(arg + sizeof(int) + (i * sizeof(u16)))

int argcount = 3;
u16 typeid = typeid(int);
u16 typeid = typeid(float);
u16 typeid = typeid(Vec2);
int arg1 = 123;
float arg2 = 0.5;
Vec2 arg2 = {};

foo(&argcount);
- Some extremely simple templates. I shouldn't have to manually declare 800 different vectors and a new array type every time I want to put a new variable into an array.
Replies: >>11621 >>11622
Nitpicks

- Fixed length types by default. u8 for unsigned char, i32 for int, f32 for float, etc. Old names can be used for flexible types where the compiler is free to change it as it sees fit for optimization or platform purposes.
- Pointer is a property of the type, not the variable. "int* foo" is more correct than "int *foo", and therefore "int* x, y" declares 2 pointers instead of a pointer and an integer.
- Ignore const when calling a function that has const arguments (you shouldn't ever have to cast a variable INTO const).
- Remove the "static" keyword. For variables it should be something like "persist", the naming for functions was elaborated above (tl;dr: static is default, public/export makes it visible).
- Ability to shift a pointer without casting, for example "foo !+ 3" gets an offset of 3 bytes from the pointer, not an offset of 3*sizeof(type).
- "alias" keyword, lets you make a new name that refers to something else. Less error-prone than using #define.
- #c_version, an optional declaration at the top of the file that tells the compiler which version of the language the file was made for. This makes it easier to change the language in the future since the compiler knows when a file expects outdated functionality, and can choose whether to implicitly support it, to give a warning, or to try to compile it with the oldest available compiler version.
- Remove "++ x" -style syntax. It causes unnecessary headaches when code golf nerds think they're being clever by cramming shit into a small space and intentionally exploiting esoteric differences like this. "x ++" is enough and more consistent with "x += 1".
- Nested functions exist globally. The point is to let you store a pointer to the inner function and call it from elsewhere after the parent function has returned.
 c
void (*foo) ();
void set_foo (int which) {
	void a () {
		printf("I am a!");
	}
	void b () {
		printf("I am b!");
	}
	if (which) foo = a;
	else       foo = b;
}
void main () {
	set_foo(1);
	foo();
	a(); // error: 'a' is undefined
}

Coming in C2X

- bool, true, false, as real keywords
- null is a keyword for a 0 value pointer, not some weird void pointer macro. While nullptr is an improvement, it's almost twice as long as it needs to be and I'll just end up doing #define null nullptr
- Binary constants, for example (0b10010110)
- Number separators, for example (10_000_000  10000000), (0b10010110  0b_1001_0110)
- {} initializes structs to 0 (same as {0} currently)
- Empty function arguments is the same as void arguments. "void foo ()" is the same as "void foo (void)"
- Binary file importing. I don't know how this works, but it better also give you a constant for the size of the file.
Replies: >>11621 >>11631
>>11619
>-  works on all types, including structs. "if (foo  bar)" just works
- =.= works on all types, including structs. "if (foo =.= bar)" just works
>>11620
>for example (10_000_000  10000000), (0b10010110  0b_1001_0110)
for example (10_000_000 =.= 10000000), (0b10010110 =.= 0b_1001_0110)

Can't we just use bbcode tags instead of this shitty formatting syntax?
Replies: >>11622
>>11621
>>11619
Oh also, all underlined words should be surrounded with 2 underscores.
>im not a retard its just that the simplest language of all time is broken and needs to fit my idiotic nonsense
Replies: >>11624
>>11623
I write more C code than everyone else on this board combined.
Replies: >>11625 >>11734
>>11624
and yet you think -> is totally arbitrary and can be replaced with . when its nothing more than syntax sugar for fucking  (*asd).asd and think you can just do a == (ie.cmp) on structs which are of arbitrary sizee and more often than not dont fucking fit in the fucking register 
yeah you clearly write so much c that the simplicity of it is so obscure to you you think it has to be fixed with nonsense only a pyshit could come up with
Replies: >>11626 >>11630
>>11625
You clearly don't write a lot of C.
Replies: >>11627
>>11626
project harder loser, i can pull out dozens of quotes that show you have no experience and jumped into c from pyshit and cant understand the simplicity of c and why its intentionally kept simple
Replies: >>11628
>>11627
If someone posted a C program in this website, there's a 90% chance the post was made by me. In this board, 100%.
Replies: >>11629
>>11628
>i posted 90% of the garbage code here therfore i m not idiot
read THIS THREAD you fucking loser, youre a complete idiot
>>11625
>you think -> is totally arbitrary and can be replaced with . when its nothing more than syntax sugar for fucking  (*asd).asd
HAHAHAHAHAHAHA holy fuck i'm dying ,sentience-free posting LMAO
>>11620
I like both your lists in general, but I would probably cut out half of the things you want just because I dislike adding arbitrary rules that have better solutions. My biggest suggestion would be removing the restriction on if(x=y) and instead augment the build system to allow for in-house linting. This would be WAY more powerful than having some authoritarian language committee trannies telling you to use the latest newspeak, which changes every day. Instead, the user has the freedom to use libraries that check their work effectively, based on their workflow and domain-specific needs. WAY BETTER. I would also extend this to multi-stage build script compilation in place of compile-time execution. In my idealized C, I think this would probably be simpler and more "C like" for the sake of implementation.

This is definitely nitpick material but I would also say that - if you were going to get serious with this - drop using any reference to C, (ie, your #c_version) and also make considerations for people who are trying to determine whether a piece of text is your C, or the original C. Main thing that comes to mind is your changing the semantics of "int* x,y;" While I agree that the original semantics were the wrong choice, I would not want to scratch my head over whether a particular file, in the wild, is using "type first" or "id first". IF THE FILE EXTENSION IS JUST .C THAT WOULD BE VERY BAD.

I get the sense that you're going for "the time machine has sent you back to 1989 and you need to fix the C99 language standard" but if we're talking about reality these sorts of practical concerns should be addressed. Anyway I'd like to post my list, but I think I'll need to take a bit of time to get everything down. It's better to present as a whole.
Replies: >>11632
>>11631
>augment the build system to allow for in-house linting
That may be better, it may also make compile times slower, but my first instinct is that it strays too far from what C is because now you can't necessarily understand the program without reading a some build system related metaprogram first. If I was completely hands-free to do anything, then I wouldn't even remake C in the first place, I would make a new language with different syntax and do metaprogramming completely differently.

>authoritarian language committee trannies
On one hand I like having more freedom, but on the other hand I have to suffer from stupid bugs caused by typos that the compiler won't warn me about because some code golf enthusiasts want the ability to save 0.2% code size by cramming a statement inside an if block header. I can remember at least 3 times that I had a bug that was caused by assigning a variable where you're expected to be comparing variables. I don't think this kind of freedom is valuable in any way to real programmers, it doesn't help you or do anything useful or give you any new capabilities, in fact it does the opposite by making certain typos not give errors which makes me feel like I'm programming in Javascript.

>I get the sense that you're going for "the time machine has sent you back to 1989 and you need to fix the C99 language standard"
Kind of, except I doubt you could fix C by using a time machine. What I'm thinking of is more like what if the C committee decided that they're dropping backwards compatibility and created C 2.0. Not a new language exactly, just a better or alternate version of the same one.
32e1b2a53071dd6f1584821125213d80e15a4b20d14b94b5d7c72083b7f27142.jpg
[Hide] (28.6KB, 640x480)
python just works
check em
Replies: >>11635
Can't you use Zig or Nim as C-replacements? I don't know much about those 2 languages but they look like good candidates.

>>11633
But it doesn't have the performance or low-level control of C.
Replies: >>11636 >>11643
>>11635
>Can't you use Zig or Nim as C-replacements?
They operate on a similar level so sure. Doesn't mean they're better though.
tl;dr can you break it down to things "Better C" from the D programming language doesn't have?
Replies: >>11651
>>11635
Zig is vaporware and has way too much boilerplate and "you do it our way" fanatism behind it to ever be successful.
The Zig compiler doesn't even compile source code with tabs in it because the developers are fanatic retards.
Replies: >>11645
>>11644
>tabs
Get a load of this fag.
Replies: >>11646
>>11645
>spaces
>current year
Anyway, why should they care about formatting at all? It should be up to the user.
>- Use . instead of -> for dereferencing struct members. It seems like a nitpick but it's important because of how prevalent and annoying and totally pointless (insert pointer joke) it is.
It should be . to dereference a pointer to struct and get the named member or simply get the named member, automatically decided based on whether it's a pointer to struct. A . over -> is because that's one less keypress. If you want to get the address of a struct member, you should do e.g. &ptv.tv_sec.

>Structs are automatically typedef'd
>Namespaced enums and automatic member picking.
>Variables do not implicitly cast
>Forbid setting variables inside "if" parentheses
> = = (equality) works on all types, including structs.
>Custom string delimiters with options
>A better way to do variable arguments. There's many ways you could handle it but anything is probably better than the half assed crap that C currently does
There is no problem to be fixed and your ideas are garbage. 
>Built-in build system
>Fixed length types by default
>Variables initialize to zero by default unless you say otherwise
>Ignore const 
>Remove the "static" keyword
>Remove "++ x" -style syntax
Not only is there no problem to fix for any of these, but you're introducing problems.
>Types for enums, and type checking (can't set a value from enum 1 into a variable whose type is enum 2, without casting).
There is no problem that this fixes.
>Bitfield type.
A "type" would be overkill. The only thing that is necessary is syntax to describe how each sequential enum is generated, this would be much more powerful and simpler.
>{} automatically casts to the target type where ever possible.
Sure.
>Anonymous structs
Already a thing.
>Anonymous structs should be compatible with each other
Again, there is no problem that this solves, and your idea is retarded.
>Ability to get the member of a struct directly from a return value
Already a thing.
>multiple return values
Have you ever heard of pointers?
>Compile-time functions
Compiler implementation detail. You have C++ braindamage.
>Make it easier to get rid of libc
Has nothing to do with C.
>16-bit floats
Maybe a floating-point type that requires even less range than the minimums and maximums float requires could be introduced depending on whether there is hardware support for this, sure.
>Switch cases break by default. "fallthrough" keyword added for falling through. "break" does not interact with switch
This is the first suggestion that fixes a real problem. Switch cases falling through by default means C does the uncommon thing by default. It should do the common thing by default.
>More run-time memory safety options
>callstack tracing
Nothing to do with C.
>better error reporting
Too vague.
>Safe version of alloca
1. Point to where alloca() is in the C standard. 
2. Do you even know C? Did you know there's something called auto storage duration that does the same thing?
3. There's nothing unsafe about alloca().
>function_id, basically func except it returns a unique integer ID for the function instead of a string for the name, starts from 1 so 0 can be treated as an error
Already a thing, take the address of the function.
>Also function_count or max_function_id so you can create an array that contains information for every function.
Perfectly doable as C currently is.
>Inline functions actually inline properly
Not C's fault. Also, what the optimizer does is the compiler's problem to begin with, C went full retard here. Your suggestions are extremely bad, but now that there is a real flaw, your text about fixing "flaws" has nothing about fixing it, instead you want to make it worse.
>Better function and variable visibility logic
Congrats on a good suggestion.
>_Generic 
Dunno, the only thing I use from C11 is atomics.
>#defines that are local to a function
Feel free to declare a variable.
>Multiline macros
Already a thing.
>#onbreak, similar to a macro, except it's automatically placed directly before all the following scope breaks (at the end of loops and if blocks, before return statements, etc) from the scope where it was defined in.
goto considered useful.
>I shouldn't have to manually declare 800 different vectors and a new array type every time I want to put a new variable into an array.
You don't.
>Pointer is a property of the type, not the variable.
Sure.
>Ability to shift a pointer
What you said doesn't make sense in C. Perhaps you're thinking about assembly.
>"alias" keyword
Learn to name things.


I don't feel like reading the rest of your post, but it shows great ignorance.
Replies: >>11652
>>11642
1. void pointers implicitly cast to other pointers
Replies: >>11658
>>11650
>I don't feel like reading the rest of your post, but it shows great ignorance.
You should look in the mirror.
Replies: >>11653
>>11652
You hardly even know C as your post shows, yet you want to "fix" it.
Replies: >>11659
>>11651
That's not much to complain about, relatively speaking.
You should use Better C then.
>>11653
I use C for making programs, not for competing how accurately I remember what I read in a book about it.
Replies: >>11660
>>11659
>I use a language I barely understand for making programs, not for competing how accurately I remember what I read in a book about it.
nooooo, the language is broken
Replies: >>11661
>>11660
Flawed.
>>11624
>I write more C code than everyone else on this board combined.
If that's true then you know that the whole point of C is that is can run on custom microcontrollers with 56Kb RAM and 16bit bytes not just your x86 "gaming" laptop. Github is full of bloated "better" C's that only compile with LLVM and 64GB of RAM and therefor can never hope to replace C where it is actually used most Rust being the most hyped example.
Replies: >>11740 >>11773
>>11734
Incorrect.
Replies: >>11741
43iv8l.jpg
[Hide] (100.3KB, 768x894)
>>11740
>Incorrect.
>>11734
I don't know why you think I would give a shit what someone else uses C for, or why that would matter for this topic in the first place. If C was better, then people who currently enjoy C would enjoy it even more.
Replies: >>11776 >>11778
cringe.png
[Hide] (657.9KB, 583x584)
>>11773
>i dont give a shit what a system language is for, if c becomes abstract javashit then kernel devs would enjoy it more
Replies: >>11777
negro.jpg
[Hide] (320.6KB, 1920x1080)
>>11776
>I didn't read, and probably can't
>>11773
>I don't know why you think I would give a shit what someone else uses C for, or why that would matter for this topic in the first place
Your topic is about creating a "better" version of C. Understanding what C is used for in the real world should be relevant. If you're just making a useless toy language to suck your own dick then the real question is why do you think we would give a shit.
Replies: >>11780
If you want to really improve a language why not make a Scheme with a tree-destructuring lambda? Fix NIL-punning and gas the boolean type and I'd hack it all day.
>>11778
How does any of the things mentioned go against your personal perception of "what C is used for in the real world"?
[New Reply]
39 replies | 5 files
Connecting...
Show Post Actions

Actions:

Captcha:

Select the solid/filled icons
- news - rules - faq -
jschan 1.1.1