Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Activity for Lundinâ€
Type | On... | Excerpt | Status | Date |
---|---|---|---|---|
Comment | Post #286975 |
@#53398 For the most part it _is_ fine to use such a variable, as in it won't cause you program to crash and burn (not undefined behavior), but it will not produce anything meaningful or deterministic either (it is unspecified behavior). With the exception of trap representations, which are mostly ir... (more) |
— | over 1 year ago |
Comment | Post #286979 |
"we can even read an uninitialized variable with unspecified value safely" This is an over-simplification. Reading a local variable (automatic storage) which was not initialized and never had its address taken (could have been declared with `register` storage class) is explicitly UB as per C17 6.3.2.... (more) |
— | over 1 year ago |
Comment | Post #286813 |
I assume you meant to write data-presentation but it is missing from the question. (more) |
— | over 1 year ago |
Comment | Post #286628 |
Ok, well... conditional compilation is always messy. I would consider solving this through version control and program design instead. As in, include a foo.h with the common interface, then link either A_foo.c or B_foo.c depending on version. (more) |
— | almost 2 years ago |
Comment | Post #286628 |
Not entirely sure what problem you are trying to solve, but is there any reason why you can't do `if (e) { _Static_assert(!e,"Called but not in binary."); } \` instead, something like that? To get a readable compile-time error instead of a mysterious link-time one? (more) |
— | almost 2 years ago |
Comment | Post #286575 |
@#53937 There are various tricks involving union type punning where the union members are pointers of different qualifiers. But that mostly relies on the C rules of effective type being underspecified in regards of type qualifiers, so I'm not sure if anyone could tell if it would be well-defined or n... (more) |
— | almost 2 years ago |
Comment | Post #286578 |
There's nothing in the C standard mentioning linking, so how and when these get linked is highly system-specific. On the average embedded system for example, each example will end up in true read-only memory at link-time. (more) |
— | almost 2 years ago |
Comment | Post #286575 |
Most of the time, you don't want to discard const qualifiers since that invokes undefined behavior in many cases. The appropriate solution is either to do a copy of the value or to reconsider your design. (more) |
— | almost 2 years ago |
Comment | Post #286440 |
@#36396 PID in the context of desktop/system programming means process identity. The less common meaning of it would be Proportional-Integral-Derivative controller. That's the two industry de facto standard meanings of the term - any other meaning isn't well established. In the context of Unix progra... (more) |
— | about 2 years ago |
Comment | Post #286372 |
The operator precedence will be the same as in basic math... so it's not even a programming problem. (more) |
— | about 2 years ago |
Comment | Post #285999 |
@#56561 This is about the code review category of this site so it doesn't apply. (more) |
— | about 2 years ago |
Comment | Post #283440 |
@#36396 If you are lucky then yes. With gcc you have to do `-Wall` to enable the warning for example. (more) |
— | about 2 years ago |
Comment | Post #286189 |
Btw I'm not saying that it shouldn't be used, I'm saying that it should be used with caution. It's an incredibly flawed function. At a minimum use a compiler which investigates the format string. Or perhaps generate the format string through some type safe interface like `_Generic` macros. (more) |
— | about 2 years ago |
Comment | Post #286189 |
@#8196 That would involve using OS-specific API though. Or in case of embedded systems, rolling out some UART or display driver manually. There's no universal replacement. Though console I/O is mostly a thing of the past, most people stopped using it around year 2000. (Programs with or without GUI ca... (more) |
— | about 2 years ago |
Comment | Post #285813 |
@#56533 No, in the first case you pass the array object and in the second case the function. As per various rules of parameter decay, the compiler will implicitly adjust them to pointers. Just as for example Java will implicitly adjust an object passed as parameter to a reference - same thing. (more) |
— | about 2 years ago |
Comment | Post #286191 |
In either of these scenarios, the correct place to check against null is _always_ where you have valid reasons to suspect it to get set to null (after a malloc call?) and only there. It is _never_ the correct place to check inside the completely unrelated library function `func` which has the purpose... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#8196 It isn't, it is the very same thing. This code `int* someptr = ...; /*...*/ if(!someptr) { ... } func(someptr); /*...*/ void func (int* someptr) { if(!someptr) { ...}` boils down to the very same thing as `int* someptr = ...; /*...*/ if(!someptr) { ... } /*some rows of unrelated code*/ if(!som... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#8196 So every 10th line or so we should check if all pointers in the current scope are null? Because that makes as much sense. (more) |
— | about 2 years ago |
Comment | Post #286191 |
Checking if you have the key before starting your car is perfectly reasonable. Checking if the car still has an engine, wheels and exhaust each time before starting it is not. What is one's reason for doing so, is there a notorious car part thief in the neighbourhood (valid reason) or is it "one cann... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#8196 Everyone is missing the point that checking for null _inside_ some generic function is always the wrong _place_. Checking for null elsewhere is perfectly reasonable and I never said otherwise. Unfortunately it would seem that the average reader here is of the PC programmer variety who has neve... (more) |
— | about 2 years ago |
Comment | Post #286189 |
@#36396 Looking them up is just a [man](https://linux.die.net/man/) away though. Some of these are rarely ever used even by C veterans. I don't think I've ever used `tmpfile` or `ungetc`, `signal()` is pretty much never used outside *nix systems and so on. (more) |
— | about 2 years ago |
Comment | Post #286189 |
@#36396 "Family of functions" means that there is `atoi` and `atof` and `atod` etc, a bunch of very similar functions with slight differences when it comes to types/parameters. And there's a corresponding more suitable family of `strtol`, `strtof`, `strtod` and so on. Similarly there is `printf`, `f... (more) |
— | about 2 years ago |
Comment | Post #286193 |
"Defensive programming", as in applying numerous error checks even in cases that theoretically shouldn't fail, might be a good idea. However, such error checks should be located near the place where one might suspect that the error appears (user input, buffer copying etc), and not in some unrelated l... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#8153 Ah yeah, silly little bug. It's been fixed, thanks. (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#53305 So now I'm not only waiting for you to explain how a C function should do bounds checking of its array parameter, I'm also waiting for you to explain exactly how `memmove_s` checks it's parameters against null, contrary to the run-time constraints in K 3.7.1.2 I just quoted. Or we could just ... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#53305 It's not "whatever", you criticise my post and down vote it with the and claim that functions should do bounds checking, which I still don't know what it has to do with null checking. I'm happy to get _constructive_ criticism but this isn't it. As for the optional annex K bounds checking inte... (more) |
— | about 2 years ago |
Comment | Post #286191 |
@#53305 How is that even related? Also I don't understand what you are talking about: either a function gets an array size passed, in which case the caller has to get it right, or it doesn't get an array sized passed, in which case no can do. Either way, a function in C cannot do meaningful bounds-ch... (more) |
— | about 2 years ago |
Comment | Post #286152 |
The thought I had when raising this question was mainly how much research effort we should require. SO went from "you have to at least understand a minimum of the topic" to "ask anything you want" and the site got IMO much worse because of it. If we aren't expecting any research effort then posters e... (more) |
— | about 2 years ago |
Comment | Post #285999 |
@#8046 Well 400 lines of very compact and detailed code with lots of comments might go as far as 30k characters... maybe. If we are looking for some worst-case number, I'd say a reasonable upper limit might be something like 1k lines 80 characters each = 80k. Larger than that and it won't be fun to r... (more) |
— | about 2 years ago |
Comment | Post #285999 |
Seriously, 400 lines of code is not much, the average source file is some 200-1000 LoC and a medium-sized project has maybe 50 such files. Sure, a whole project like that would be too much, but why wouldn't the site be able to take a 400 LoC post? (more) |
— | about 2 years ago |
Comment | Post #285974 |
As a side note regarding embedded systems and main(), there's an issue where C++ claims that if main() is defined, it must be declared as int main() and I don't even think they made an exception for freestanding systems. In that case `noreturn` might save the day. That doesn't apply to C however, wh... (more) |
— | about 2 years ago |
Comment | Post #285974 |
@#53937 I wouldn't dare say anything about ABI compatibility between all *nix systems that have implemented pthreads over the years. Just take x86_32 Linux vs x86_64 Linux as the most obvious example. (more) |
— | about 2 years ago |
Comment | Post #285974 |
@#53398 Again, you can't do that for the same reasons as in my previous comment - calling convention. If you specify a return type but don't return, you risk tricking the compiler into thinking it should push/pop items on the stack which are never pushed/popped there by the function. This is also the... (more) |
— | about 2 years ago |
Comment | Post #285974 |
@#53937 Never the less, it is bad practice not to clean up your own mess no matter what the OS does. Executing such clean-up code is also an excellent way of surfacing dormant bugs elsewhere in the application (`free()` crashing etc). (more) |
— | about 2 years ago |
Comment | Post #285974 |
@#53398 The whole practical rationale for this is cases like for example a "bare metal" system where your program starts up in a power-on reset interrupt. From there on it calls the C run-time start-up code _never to return_, so no need to waste stack on storing return address etc. Then the C run-tim... (more) |
— | about 2 years ago |
Comment | Post #285968 |
@#53078 The C standard is fuzzy and only says that the pointed-at data should be regarded as an array of objects with "a fundamental alignment requirement" (an alignment less than or equal to the greatest alignment supported by the implementation in all contexts). So the alloc functions may grab more... (more) |
— | about 2 years ago |
Comment | Post #285969 |
Discussion about resource requests specifically: [How does the community feel about resource requests?](https://software.codidact.com/posts/277530) (more) |
— | over 2 years ago |
Comment | Post #285911 |
Also related: [The size of the code format window is much too small.](https://software.codidact.com/posts/278868) (more) |
— | over 2 years ago |
Comment | Post #285957 |
@#8196 All of these are artificial examples. The whole point of using forward declaration in the context of opaque types is to block the caller from knowing anything about that type - which as it happens means that they won't know the struct size either. As for dynamically allocating an array of func... (more) |
— | over 2 years ago |
Comment | Post #285956 |
@#8196 And how exactly is it less duplication to increase the references to the `p` identifier from 3 times to 6 times? Imagine if it isn't called `p` but `long_contrived_name_foo`, which happens to have a sibling `long_contrived_name_bar` and if we mix up these identifiers, everything will crash & b... (more) |
— | over 2 years ago |
Comment | Post #285956 |
@#53305 That's an excellent argument actually. The argument in favour of this `sizeof *p` style is that someone would aimlessly change the _type_ of a variable without checking the code using that variable. But what if they change the _identifier_ of that variable instead - again without checking the... (more) |
— | over 2 years ago |
Comment | Post #285956 |
Actually, after giving this some thought... a compiler must yield a diagnostic message when de-referencing a void pointer _and passing it to `sizeof`_. Both gcc and clang do this in `-pedantic` mode. They are required to do so by constraints 6.5.4.3 regarding the sizeof operator. So yes something is ... (more) |
— | over 2 years ago |
Comment | Post #285956 |
De-referencing void pointers is not allowed as per 6.3.2.2 "The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way, and implicit or explicit conversions (except to void) shall not be applied to such an expression." Clang seems to fail in issuing a... (more) |
— | over 2 years ago |
Comment | Post #285956 |
`p[i][j]); // Add asterisk to p[i][j]` Shouldn't it be `*p[i][j]`? (more) |
— | over 2 years ago |
Comment | Post #285946 |
`_Nonnull` don't use this. First of all, convention gives that this ought to be the caller's responsibility. Second, if you insist on using such features, the standard already has support for this through `static`. And lately compilers also have added support for it. So if you wish to protect against... (more) |
— | over 2 years ago |
Comment | Post #285910 |
@#8196 The equivalent `int (*p)[5]` would have been just as problematic. There's plenty of examples where the style simply doesn't work well. (more) |
— | over 2 years ago |
Comment | Post #285899 |
@#53937 Really? I haven't heard about that and the C committee hates fixing language flaws at the expense of backwards compatibility. Such a radical change would be nice but it also means that all C code out there won't be compatible with C2x. (more) |
— | over 2 years ago |
Comment | Post #285899 |
Expect casting to the expected type is a common way to dodge implicit promotions, so doing so might actually be considered good practice depending on context. For example MISRA-C wouldn't allow this code `unsigned short a,b; ... signed int c = a + b;` but require `c = (signed int)(a + b)`. Though thi... (more) |
— | over 2 years ago |
Comment | Post #285908 |
You could take the live production database and have it copied to a second instance on regular basis, for example at the same time when backups are running.
This identical, continuously updated copy of the real database becomes your test one, where you are free to play around. This also allows you... (more) |
— | over 2 years ago |
Comment | Post #285899 |
The forgetting stdlib.h argument was what once started the whole "don't cast the result" business, where otherwise people wouldn't care much about the cast. Bugs caused by C90 implicit int are _not_ fun to debug, they are subtle as sin. It was a very valid argument back in the 1990s. Today, not so mu... (more) |
— | over 2 years ago |