I just want to get to the bottom of thingsWell, then, catch the brainwasher.
Play around with the number type "value", right in the function.
https://godbolt.org/z/son3EsKaK
#include <stdint.h>
const char toa_basis[] = "0123456789abcdef";
char toa_error[4] = "(?)";
// Note: sizeof(toa_basis) == strlen(toa_basis) + 1
#define TOA_RADIX_MAX (sizeof(toa_basis) - 1)
static char internal_umaxtoa(uintmax_t val, char *dst, int radix)
{
// Verify valid radix.
if (radix < 2 || radix > (int)(TOA_RADIX_MAX))
return 1; // Error
// Construct string starting with the least significant digit of 'val',
// using a helper pointer 'end' since we need original value of 'dst' later.
char *end = dst;
do {
// Current least significant digit in 'val' base 'radix'; then advance 'end'
*(end++) = toa_basis[val % radix];
// Drop next digit into the least significat digit place.
val /= radix;
// Repeat if 'val' is nonzero.
} while (val);
// Terminate the string.
*end = '\0';
// Now we have the numeric string in reverse order, from *dst to *(end-1).
// For example, 1234 in decimal will yield "4321" with end==dst+4.
// Reverse the string by swapping characters.
while (dst < --end) {
// We already decremented end to point to the char itself,
// and need to swap '*dst' and '*end', and then increment 'dst'.
const char c = *dst;
*(dst++) = *end;
*end = c;
}
// Successful conversion.
return 0;
}
// dst must have room for at least 1+ceil(log(val)/log(radix)) chars.
char *umaxtoa(uintmax_t val, char *dst, int radix)
{
// If 'dst' is NULL, we can only error out.
if (!dst)
return toa_error;
// Do the conversion using internal helper function.
if (internal_umaxtoa(val, dst, radix)) {
// Nonzero return value: Make 'dst' be an empty string, and return error.
dst[0] = '\0';
return toa_error;
}
// Success. Return 'dst'.
return dst;
}
// dst must have room for at least 2+ceil(log(abs(val))/log(radix)) chars.
char *imaxtoa(intmax_t val, char *dst, int radix)
{
// If 'dst' is NULL, we can only error out.
if (!dst)
return toa_error;
if (val < 0) {
// Do the conversion using internal helper function, but skip the first char in 'dst'.
if (internal_umaxtoa(-val, dst+1, radix)) {
// Nonzero return value: Make 'dst' be an empty string, and return error.
dst[0] = '\0';
return toa_error;
}
// Success. Set the negative sign, and return a pointer to it.
dst[0] = '-';
return dst;
} else {
// Do the conversion using internal helper function.
if (internal_umaxtoa(val, dst, radix)) {
// Nonzero return value: Make 'dst' be an empty string, and return error.
dst[0] = '\0';
return toa_error;
}
// Success.
return dst;
}
}
These have been tested to produce identical outputs to snprintf(buf, sizeof buf, "%ju", uval) for all 33-bit unsigned integers (and a few hundred million random 64-bit unsigned integers), and to snprintf(buf, sizeof buf, "%jd", ival) for all 33-bit signed integers (and a few hundred million random 64-bit signed integers), in base 10.Just limiting ourselves to the interfaces existing libraries provide –– including the above functions I have posted to this thread! –– may make the code slightly easier for others to maintain (in the sense that when they write code using these without consulting the documentation, the implementation makes typical bugs other than too-short buffer obvious in testing), but not true advancement.
C sucks to begin with. So what.
C core language is still quite A) consistent, B) powerful. Standard library on the other hand is very inconsistent and limited in its abilities (so that programmer needs to re-write simple things over and over again), it looks like some people just cobbled something together in 1970's and then it was locked down with no changes allowed.
C core language is still quite A) consistent, B) powerful. Standard library on the other hand is very inconsistent and limited in its abilities (so that programmer needs to re-write simple things over and over again), it looks like some people just cobbled something together in 1970's and then it was locked down with no changes allowed.
C core language was cobbled together in the 1970 in the same haphazard way than the libraries. If it feels consistent to you it's just because you've got accustomed to its idiosyncracies (it also helped a bit that it was thrown together basically by one person in a relatively short timespan).
"Powerful" is relative. Would it be powerful enough, most of what is in the standard libraries would be integral part of the language.
The single powerful feature of C is, that it does exist.
My point is not to bitch about C or the stdlib, though. My point is, that it is what it is, learn to live with it, according to your particular needs.
At the end of the day, any replacement would have its own idiosyncracies, too, and we'd just discuss those then.
And there's no one size fits all.
JW
#include <stdio.h>
int main() {
printf("Oh, I see. You want aggression and annoyance, do you? Well, brace yourself for a dose of unapologetic bluntness.\n");
printf("It's amusing how you dismissively refer to the C programming language as being cobbled together in a haphazard manner. Allow me to remind you that C was meticulously designed by the legendary Dennis Ritchie, a pioneer in the field of computer science. It was his brilliance that birthed this powerful language, which has withstood the test of time and continues to be a cornerstone in the world of programming.\n");
printf("You seem to belittle the C standard library, claiming that if C were truly powerful, everything in the libraries would be integrated into the language itself. Let me enlighten you, my friend. The standard library is a separate entity precisely to maintain a modular and lightweight core language. It allows developers to add functionality as needed, keeping the language lean and adaptable. This approach has empowered programmers to create countless libraries and frameworks that extend the capabilities of C.\n");
printf("Oh, and your assertion that the single powerful feature of C is its existence? That's just a feeble attempt at oversimplification. C's power lies in its efficiency, its low-level control, and its ability to interact closely with hardware. It's the language of choice for system programming, where performance and optimization are paramount. Its influence can be seen in countless software systems that underpin the modern world.\n");
printf("Now, let's address your defeatist attitude. Instead of whining about C's idiosyncrasies, why not embrace them as the unique flavor that defines the language? Every programming language has its quirks, and C is no exception. It's about time you accept that fact and adapt to the realities of the language you're working with. If you can't handle it, maybe it's time to step aside and let the true C aficionados take the reins.\n");
printf("And finally, your remark about there being no one-size-fits-all solution. Well, congratulations! You've stumbled upon an obvious truth. But don't use it as an excuse for mediocrity. The beauty of programming is in the diversity of languages and tools at our disposal. Instead of settling for complacency, we should strive to find the best fit for each unique problem and push the boundaries of what's possible.\n");
printf("So, my exasperating friend, if you're going to criticize C, at least do so with some intellectual rigor and a genuine understanding of its strengths and legacy. Otherwise, your complaints come across as nothing more than the futile grumblings of an ignorant provocateur.\n");
return 0;
}
With no help from ChatGPT (cough cough).
C sucks to begin with. So what.
C core language is still quite A) consistent, B) powerful. Standard library on the other hand is very inconsistent and limited in its abilities (so that programmer needs to re-write simple things over and over again), it looks like some people just cobbled something together in 1970's and then it was locked down with no changes allowed.
C core language was cobbled together in the 1970 in the same haphazard way than the libraries. If it feels consistent to you it's just because you've got accustomed to its idiosyncracies (it also helped a bit that it was thrown together basically by one person in a relatively short timespan).
"Powerful" is relative. Would it be powerful enough, most of what is in the standard libraries would be integral part of the language.
The single powerful feature of C is, that it does exist.
My point is not to bitch about C or the stdlib, though. My point is, that it is what it is, learn to live with it, according to your particular needs.
At the end of the day, any replacement would have its own idiosyncracies, too, and we'd just discuss those then.
A first step would be to move over to C++ with better string handling and needing less dealing with pointers.
Sorry, I do not understand. Was my example code gibberish?
Code bloat is something that is seemingly very hard to resist.
This is an almost lost cause in the software industry, except in very niche areas such as safety-critical stuff.
As others have already pointed out, it just happens to be that the C standard library API sucks to begin with.C sucks to begin with. So what.
JW
I don't think C sucks. Sure there are some things that are borderline evil like unsafe functions like gets etc. but I much prefer C over C++.
Just limiting ourselves to the interfaces existing libraries provide –– including the above functions I have posted to this thread! –– may make the code slightly easier for others to maintain (in the sense that when they write code using these without consulting the documentation, the implementation makes typical bugs other than too-short buffer obvious in testing), but not true advancement.True advancement doesn't come from C. A first step would be to move over to C++ with better string handling and needing less dealing with pointers. Even better would be Python (for larger targets) or Lua (for smaller targets) to reduce NRE costs. I expect prices of microcontrollers to drop sharply over the next years so memory size becomes even less of an issue.
"gets" is not C, it's library, and you don't have to use it.
So, [C standard library is] technically not part of the language (syntax etc.) but practically speaking it is, because no-one in their right mind would re-write the standard library without a really strong case for it.
Many software projects like the Linux kernel are developed purely in the freestanding C environment.
Thus, it really is an error to think of the C standard library as an irremovable part of the C language.
I was talking about application level code.
If you told me that you re-wrote malloc (which is part of the standard C library) for a project (that runs on an modern OS) then I would tell you that this is stupid.
Thus, it really is an error to think of the C standard library as an irremovable part of the C language.I agree with that, although I'm not sure why you would tell me, because I said "I never said it's part of the language." above.
If you told me that you re-wrote malloc (which is part of the standard C library) for a project (that runs on an modern OS) then I would tell you that this is stupid.I agree, if we are talking about writing our own malloc()/realloc()/free() functions.
But, I am not: I am talking about replacing such things with completely new functions.
I only showed the xxxtoa() implementations as a concession, to discuss the details of numeric-to-string conversion only; I do not use that interface in code I write myself.
When I talk about replacing the standard C library, I mean with something other than the interfaces defined for the standard C library in the hosted environment. If I were to talk about writing my own implementation of the hosted environment standard C library, I'd use 'reimplement the standard C library'.
I was talking about application level code.
If you told me that you re-wrote malloc (which is part of the standard C library) for a project (that runs on an modern OS) then I would tell you that this is stupid.
This begs the question: why doesn't such a library exist yet? For C++ there are various libraries / frameworks like Boost, Qt, Wxwidgets which are very popular that sit between applications and the standard libraries. Even if you don't need code to be portable, these libraries / frameworks are super usefull. I'm not aware of anything similar existing for plain C.
This begs the question: why doesn't such a library exist yet? For C++ there are various libraries / frameworks like Boost, Qt, Wxwidgets which are very popular that sit between applications and the standard libraries. Even if you don't need code to be portable, these libraries / frameworks are super usefull. I'm not aware of anything similar existing for plain C.I think those are different. They can't replace the C++ standard library because they do not offer better/different interfaces to nearly all of the usual problems. Instead, they add to the standard library (e.g., threads, networking...). Additionally, these are quite complex beasts which are arguably bloated, difficult to use, with significant learning curve, some of which is inevitable because they are solving more complex problems.
Ah, okay. I thought/assumed this was about code running on a microcontroller or similar embedded and constrained devices.
I agree, if we are talking about writing our own malloc()/realloc()/free() functions.
But, I am not: I am talking about replacing such things with completely new functions.
I only showed the xxxtoa() implementations as a concession, to discuss the details of numeric-to-string conversion only; I do not use that interface in code I write myself.
When I talk about replacing the standard C library, I mean with something other than the interfaces defined for the standard C library in the hosted environment. If I were to talk about writing my own implementation of the hosted environment standard C library, I'd use 'reimplement the standard C library'.
I've mentioned it before, but the lack of strdup(), strndup(), getline(), getdelim(), asprintf(), vasprintf() etc. in the standard C library is utterly silly. They are widely used, and definitely help write more robust real-world systems or application-level code. (Some of them are in POSIX, some are GNU only, some have BSD equivalents.)
To me, this is proof of the stagnation of the standard library part of the C language.