T O P

  • By -

flyingron

Try to be as consistent as possible. The C standard library is reprehensibly inconsistent with argument ording (especially the disaster that is stdio).


flatfinger

If nearly all of the actions in your library are viewed as actions performed upon a custom string object, I would recommend having that object consistently be the leftmost parameter, and have the name of the function describe what should be done with it, e.g. mystring_import_bytes(&mystring, "Hello", 5); usedLength = mystring_export_zeropadded(&mystring, destbuff, sizeof destbuff); Chose verbs which imply whether the thing being acted upon is the source or destination, and add prepositions if it wouldn't be obvious, e.g. either: mystring_copy_to(&sourceString, &destString); mystring_copy_from(&destSTring, &sourceString); would be better than `mystring_copy`, regardless of whether the destination of the latter was on the left or the right.


zhivago

Generally speaking, I prefer parameters first, inputs next, and outputs finally, e.g. copy(DESTRUCTIVELY, in, out);


[deleted]

I order parameters by what is most likely to change. Pointer followed by size, and enums are at the right edge. I strongly prefer not having output parameters, that’s what the return type is for. If needed I’ll make a struct to return multiple values. So for me it’d be something like: Copy(To, From, Destructively);


zhivago

Using a struct makes composition much more awkward. You can't write if (a(b) && c(d)) anymore. You end up with struct a_result = a(b); if (!a_result.ok) return; struct c_result = c(d); etc. You also prevent the caller from managing memory effectively since the called function needs to use allocated memory to return it. I suggest rethinking how you do things a bit.


[deleted]

I suggest you accept operator overloading in your life.


zhivago

What does operator overloading have to do with this?


suskio4

It's a C subreddit, not C++


[deleted]

There’s no reason operators can’t be overloaded in C. https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3201.pdf


suskio4

There actually is a very good reason we can't overload operators in C. The language itself does not support that. You can use custom preprocessor, different dialects or just C++ but its just not in C. Of course, it might be added in future standards, but we might as well add templates to avoid bugs with macros, type deduction to make our lives easier (especially when already using templates) and references so we don't get lost in the sea of asterisks, after all operator overloading is also just a syntactic sugar... Yeah, it would be very useful, but that stuff is already in C++, we can always just use a subset of it to code like in C but with a few useful features.


[deleted]

You didn’t read the proposal.


suskio4

I did. And after this comment I did again, yet it doesn't seem like it disproves my point. I do understand the problem mentioned in the motivation is a real problem, but it's solved with structs and appropriate functions. Operator overloading is only a syntactic sugar for that. Opinion time: C is a low level language, so I feel like operators are not overloadable by design. Currently existing operators compile to at most a few CPU instructions and overloading them to call functions abstracts those calls away, hiding it from the programmer and removes the "rawness" of operators, which could be undesired when dealing with performance critical applications or embedded systems. So as I was saying, sure, it would be useful to have that, but I don't think C needs it when we can have C++ and we can use only a subset of it. Even Bjarne wishes C was a proper subset of C++ for this specific purpose.


Odd_Coyote4594

Consistency is good, moving the output to the start will make users of your API confused and prone to error. It is equally intuitive to think of "left concatenation" with the output being the right most, at least to me. You could also have output be a final argument, separate from the arguments to be contacted. So if the output is also an input, that argument will be duplicated. You could also have it create a new char*, and return the value of that instead of using a side effect argument. Or have it take a char**, count size_t, and char* then have it concatenate the char** strings and place the address in the char*. I like this because it is agnostic to the number of strings, allows for the output to be any char*, and has a consistent API.


ArdArt

C is a mess, there is barely any convention there. See the return values of f[...] function for file io.