What do you consider good style in C, Sup Forums? Any conventions or design patterns you follow?
What do you consider good style in C, Sup Forums? Any conventions or design patterns you follow?
Deez nutz
k&r / linux kernel style
int
main()
{
for ( int i = 0; i < 100; ++i ) {
if ( somecondition ) {
}
}
}
Spaghetti
man.cat-v.org
If you're using C you shouldn't be dogmatic.
You can't afford it.
If you could you could switch languages.
there's only two ways to make this look good
int main() {
for (int i = 0; i < 100; ++i) {
if (some_condition) {
/* ... */
}
}
}
int main()
{
for (int i = 0; i < 100; ++i)
{
if (some_condition)
{
/* ... */
}
}
}
no exceptions
Code that can be read easily.
#1 feels nicer to write, #2 feels nicer to read. In my experience, at least.
this
Literally wrong.
Have you ever seen a C# codebase? It's considered proper for ALL brackets to be on their own lines so you end up with these 800 line files that barely do anything
>nicer to write
I had barely considered that a factor.
Do you have a problematic return key?
Do you not have tools that let you automatically format?
I despise reading code of style 2.
Whitespace isn't automatically good and I'm not a particular fan of having a simple algorithm be spread over two screens of code just because you need to add a redundant try-catch for stability.
any good codebases out there to check out?
>there's only two ways to make this look good
Correct. 1) Leave it alone 2) It's already perfect
Return type
Function Name (parameters)
{
}
Is how functions should be written, everything else that needs brackets should be Java-style.
this but put the return type same line as the function name
>but muh pointers
then you do that
Pointers hug the variable's name.
char *str[12];
In that way, you get the variable's value just by copying the declaration.
char a = *str[5]; // Get the first character of the sixth string.
>tfw you're a newfag who can't code block.
int main(int argc, char **argv)
{
}
You just read as many data-oriented things as possible.
k&r, Linux, OpenBSD's KNF, slightly pike-style, 8-sized indent.
I like function return type on separate line, this looks ugly at first for simple things like returning int, but when you return static struct something * it starts being worth it.
There is one thing I really wish to know about those styles: the promote opening bracket of function at new line but inlined for loops etc. Does it come from old declaration style?
int
main(argc, argv)
int argc;
char *argv[];
{
wiki.sei.cmu.edu
clarity and readability > number of characters
I still can't get used to (!something) over (something != NULL) and/or (something != 0), I like the type indices here. But everybody recommends negation.
Void in arguments of function declaration when empty, this raises compilation error when arguments provided.
Gotos are not absolute evil, they are valid at the end of function to jump to cleaning when error handling since there is no RAII (except compiler extensions which doesn't fit all scenarios anyway).
Old-fashioned include guards, no #pragma once, maybe in C++ if winfag from day zero, but that's not my case.
I agree with everything in this post except for function name on newline.
>Does it come from old declaration style?
Yes.
>this but put the return type same line as the function name
The pajeet C shibboleth.
Ok this arguing about braces and shit is cool and all but I actually kinda wanna know more about writing good C code. Coming from the traditional OOP background (leaving me blind to this kind of stuff) it'd be nice to see some examples of what's considered good C
Good C is following the hardware, making things simple and not using OOP methodologies that focus on abstraction at the cost of maintainability and performance.
Here's the best starting talk on that.
youtube.com
After that you can argue if pointer aliasing and SSE/SIMD instructions are worth your time.
I use code generation to do OOP in C, and there's nothing you can do about it:
// codegen:
struct thing;
struct thing_vtbl;
struct thing_data;
int32_t thing_read_prv(struct thing *f, int32_t length, uint8_t *buffer);
int32_t thing_write_prv(struct thing *f, int32_t length, const uint8_t *buffer);
void thing_close_prv(struct thing *f);
const struct thing_vtbl {
int32_t (*read)(struct thing *, int32_t length, uint8_t *buffer);
int32_t (*write)(struct thing *, int32_t length, const uint8_t *buffer);
void (*close)(struct thing *);
} thing_vtbl_prv = {
thing_read_prv,
thing_write_prv,
thing_close_prv
};
struct thing {
const struct thing_vtbl *vtbl;
struct thing_data *data;
};
int32_t thing_read(struct thing *f, int32_t length, uint8_t *buffer) { return f->vtbl->read(f, length, buffer); }
int32_t thing_write(struct thing *f, int32_t length, const uint8_t *buffer) { return f->vtbl->write(f, length, buffer); }
void thing_close(struct thing *f) { f->vtbl->close(f); }
// actual implementation
int32_t thing_read_prv(struct thing *f, int32_t length, uint8_t *buffer) { return 0; }
int32_t thing_write_prv(struct thing *f, int32_t length, const uint8_t *buffer) { return 0; }
void thing_close_prv(struct thing *f) { return; }
What are you doing here? Virtual functions?
You don't need OOP.
I like to have decoupled components that interact through interfaces, which can be mocked in unit tests.
Here's the sane version of GNU coding style.
int
main(int argc, char *argv[])
{
struct gizmo foo;
fetch_gizmo(&foo, argv[1]);
check:
if (foo.type == MOOMIN)
puts("It's a moomin.");
else if (foo.bar < GIZMO_SNUFKIN_THRESHOLD / 2
|| (strcmp(foo.class_name, "snufkin") == 0)
&& foo.bar < GIZMO_SNUFKIN_THRESHOLD)
puts("It's a snufkin.");
else {
/*
* pointer to the first character after
* the last stash in the file name
*/
char *barney;
int wilma; // approximate size of the universe
int fred; // max value of the `bar' field
do {
frobnicate(&foo, GIZMO_SNUFKIN_THRESHOLD,
&barney, &wilma, &fred);
twiddle(&foo, barney, wilma + fred);
} while (foo.bar >= GIZMO_SNUFKIN_THRESHOLD);
store_size(wilma);
goto check;
}
return 0;
}
First one is concise and the most common coding standard.
Nr. two is an abomination that only lives within the C community and is getting used by people who are special snowflakes. It's simply a waste of space to use this reddit spacing..
>b-but it's more readable!
>I need an empty line for my well being!
>Your code is suffocating me!
Sure, and let's also add differnt colors and fonts, you fucking queers.
>Components
>Interfaces
>Unit tests
You don't need any of this stuff.
>Nr. two is an abomination that only lives within the C community and is getting used by people who are special snowflakes. It's simply a waste of space to use this reddit spacing..
number 2 is M$ style pushed by Visual Studio formatter across C, C++ and C# (and maybe more).
He's probably a closet Java dev who didn't have his coming out yet..
Indeed, I'd use Java if my microcontroller could run the JVM.
I'm not sure this is helping your point, mang.
I honestly love doing shit like:
template
const
T&
mystruct:mymethod()
It's far more readable.
I realize that we're talking about C, but using it to illustrate separating different concerns, templates, constness, actual return type, etc...
[/code]
>windows was written this way
>literally the largest PC OS
>only snowflakes use it hurr durr
sure thing soyboy
What's the matter, does your teletype terminal only support 80x25? Do you love Python's indent-as-scope too?
int
main
{
int
i;
for
( i = 0 ; i < 10 ; i++ )
{
// extra spacing for better readability
// code starts here:
}
}
ah, but that's reddit-style coding though, a different style altogether, nobody wants that. Still see nothing wrong with curly braces being on seperate lines though, but must admit I agree with this user:
struct {
int i, j, k;
};
//or...
struct
{
int i, j, k;
};
I just run my source code through indent -kr
I separate different concerns onto different lines, but the return type still goes on the same line. It all forms a single type declaration, and you should keep that in mind in case you want to return a pointer to a function or an array.
template
constexpr static inline
void (*function())();
I guess you could use trailing return types though.
Banner for life.
int main( ) {
for( int i = 0; i < 100; ++i ) {
if( somecondition ) {
// smth
}
}
}
int
main(void)
{
int *pointer;
for (int i = 0; i < 100; i++)
{
if (some_condition)
{
function_call(i);
}
}
}
Why are all your brackets on the wrong indents?
i personally follow openBSD style with some minor changes but linux kernel and k&r are also good.
I dislike GNU's bracketing style so i avoid that shit
C doesn't have "design patterns" really because it isn't an OOP language, and those design pattern books are generally full of shit anyway.
Mozilla style. Respectable.
because he can't use clang_format
int main()
{
for (int i=0; i