|
I'm not saying that types in C are interchangeable, nor do I approach programming that way. I'm pretty much just asking about why variables in C are defined like that, while trying to provide my own reasoning as to why it may make sense to consider it to be a reasonable syntax in some context. My argument is, it is that way because you're more concerned with the actual value in memory (and how big it is, for the aforementioned reasons), and * or [] are only specifying how it is stored, accessed, or allocated. Furthermore, considering such types in C to be actual types that are sanely enforced like they maybe should be is what causes problems.raminasi posted:The less "I told you so" reason is that the C standard uses the type system to make its specifications, so ignoring or abbreviating it means you're likely to accidentally wander into undefined behavior. You thinking that two things are equivalent doesn't mean the compiler agrees with you, and you're not the one doing codegen. Ok that makes sense because I'm the guy that does *(t*)&x and I suppose the right thing to do is to uses memcpy but my father never taught me these things I guess. It always works with stdint, so I dunno. I mean, I think I only do it to swizzle things too, I can't remember. Actually I do remember and it's usually for parsing packets/datagrams/etc... after I've done some simd magic. I typedef structs too so I'm probably the worst C programmer on both ends of the spectrum. dougdrums fucked around with this message at 23:32 on Nov 10, 2016 |
# ? Nov 10, 2016 23:04 |
|
|
# ? Jun 8, 2024 02:43 |
|
The historical rationale for the spelling of pointers in C was an idea called "declaration follows use" which held that the clearest way of spelling things would be to have the declaration of the thing mirror the usage of that thing. I don't personally think of it as a successful experiment.
|
# ? Nov 10, 2016 23:35 |
|
Ah, that's what I wanted to know, but I wasn't sure how to find it. I'm not sure I agree with it either but I'm real tired of hearing, "I don't understand (thing) but that's so dumb and useless and C killed my dog" just because they read it on some dipshits blog or something. I mean I didn't know but I figured there was some rational behind it.
|
# ? Nov 10, 2016 23:48 |
|
dougdrums posted:Ah, that's what I wanted to know, but I wasn't sure how to find it. I'm not sure I agree with it either but I'm real tired of hearing, "I don't understand (thing) but that's so dumb and useless and C killed my dog" just because they read it on some dipshits blog or something. I mean I didn't know but I figured there was some rational behind it.
|
# ? Nov 11, 2016 02:21 |
|
dougdrums posted:Ah, that's what I wanted to know, but I wasn't sure how to find it. I'm not sure I agree with it either but I'm real tired of hearing, "I don't understand (thing) but that's so dumb and useless and C killed my dog" just because they read it on some dipshits blog or something. I mean I didn't know but I figured there was some rational behind it. C and C++ are terrible, probably killed multitudes of dogs and the correct way is to always have the * next to the type, even if C's syntax is horrible and disagrees. Hope this helps (Modern C++ is still my preferred language though ) dougdrums posted:Ok that makes sense because I'm the guy that does *(t*)&x and I suppose the right thing to do is to uses memcpy but my father never taught me these things I guess. It always works with stdint, so I dunno.
|
# ? Nov 11, 2016 16:33 |
|
Ralith posted:That is, however, purely a matter of syntax. It's still part of the type. Yeah, it's difficult to express that I'm only really referencing the syntax. I understand that those two go together to specify the type. The person in reference was asking why it might make sense for someone to write int *x[2]; instead of the more modern syntax. I would say x are ints accessed in that manner to describe why that syntax might make sense, I mean that's what I always figured. I'd only hear, "but x is the type of an array of int pointers, so it's wrong". Sure, that's accurate, but I understand how splitting up the data type and how its operated on makes some sense, especially at a lower level. Today I argued some more and managed to express why the syntax is that way, and the returning argument was that, "it's too difficult for new programmers to understand." I mean, OCaml took me a little while to get used to. Everything new is difficult when you're not used to it ... I didn't really question it when I started learning C years ago. I guess I'm just dismayed that my fellow programmers can't hear out some different perspective without some arm twisting. Either way everyone except the densest C programmers would probably accept that the 'split' syntax of pointer and array definitions (function pointers in particular...) is a little silly. Xarn posted:C and C++ are terrible, probably killed multitudes of dogs and the correct way is to always have the * next to the type, even if C's syntax is horrible and disagrees. Hope this helps Hah, I've never considered it, but C is probably responsible in some manner for killing someone's dog somewhere I'm sure. Also I've gotten some poo poo for doing *(t*)&x before and I know its definitely undefined as gently caress. Does a data-type sized memcpy usually compile to a different pointer size for addressing in machine code? If I had it my way, we'd only have the types wire and reg
|
# ? Nov 11, 2016 19:22 |
|
dougdrums posted:Hah, I've never considered it, but C is probably responsible in some manner for killing someone's dog somewhere I'm sure. Also I've gotten some poo poo for doing *(t*)&x before and I know its definitely undefined as gently caress. Does a data-type sized memcpy usually compile to a different pointer size for addressing in machine code? The times I bothered checking (usually I couldn't care less if it does the most efficient thing), the code generated by using memcpy was same, or even better (Ok, I only saw that once )
|
# ? Nov 11, 2016 21:50 |
|
Compilers know about memcpy and will generate the optimal memory-copying sequence. They will also not enforce the type-based aliasing rules, because memcpy is specified to ignore them, which in your case is good because that cast is almost definitely a violation.
|
# ? Nov 12, 2016 00:08 |
|
dougdrums posted:I've always considered * & and [] to be more like compiler directives instead of actual typed values You can consider them whatever you want, but pointers are their own type, not just a syntax layer on top of whatever they're pointing to. This is generally true all the way down to the hardware.
|
# ? Nov 12, 2016 01:52 |
|
Klades posted:You can consider them whatever you want, but pointers are their own type, not just a syntax layer on top of whatever they're pointing to. This is generally true all the way down to the hardware. [] in C genuinely is syntactic sugar for pointers, though.
|
# ? Nov 12, 2016 17:16 |
|
feedmegin posted:[] in C genuinely is syntactic sugar for pointers, though. I disagree. I also think that the temptation to believe this is one of the most pernicious traps of learning C. You have only to see what happens when you pass a struct containing an array as an argument to a function versus when you pass a struct containing a pointer as an argument to a function to understand that this view is mistaken.
|
# ? Nov 12, 2016 18:07 |
|
Fergus Mac Roich posted:I disagree. I also think that the temptation to believe this is one of the most pernicious traps of learning C. You have only to see what happens when you pass a struct containing an array as an argument to a function versus when you pass a struct containing a pointer as an argument to a function to understand that this view is mistaken. I believe the claim was made with respect to [] array accesses, not definitions, presumably in reference to the [5]butt trick.
|
# ? Nov 12, 2016 18:30 |
|
Fergus Mac Roich posted:I disagree. I also think that the temptation to believe this is one of the most pernicious traps of learning C. You have only to see what happens when you pass a struct containing an array as an argument to a function versus when you pass a struct containing a pointer as an argument to a function to understand that this view is mistaken. It's true for function signatures, not elsewhere.
|
# ? Nov 12, 2016 18:31 |
|
How can I see some kind of listing/mapping of what kind of function calls does which part of my code cause? Reason for the question is that I am interested in using C++ for an embedded application (with no OS so no dynamic memory allocation, exceptions etc.). I know there are various pitfalls and things you shouldn't use, but instead of just blindly trusting some list of features not to use I would like to try to port some code (desktop) of mine for embedded and identify problematic parts myself. So basically what I would like to see that function fooBar() calls std::vector<T>() and that calls malloc() or new() or whatever so I can spot which features/calls call something that will be a problem. I know you can get a backtrace from a debugger and so forth but I guess there has to be some more comprehensive way to extract all of this information at once and dump to a file. Maybe from the linker somehow?
|
# ? Nov 15, 2016 12:01 |
Hyvok posted:How can I see some kind of listing/mapping of what kind of function calls does which part of my code cause? What you're after is probably a call graph. Various static analysis tools should be able to produce one. Which tool to get depends on what compiler/toolchain you're otherwise using.
|
|
# ? Nov 15, 2016 12:31 |
|
feedmegin posted:[] in C genuinely is syntactic sugar for pointers, though. [] degenerates to pointer in a function call, but they are definitely not the same. Plus, if you care about performance, your compiler will thank you for using [] where appropriate instead of manually degenerating into pointer type everywhere. I frequently use functions that take: "void double (*arr)[8]" arguments, even for 1D arrays. As lovely and poor the C/C++ type systems are, you can still use it to pass extra semantics to the compiler. Note that it has still not been shown that stronger and/or stricter type systems makes you code easier or safer. It seems to be taken as a given. It avoids you making the simple mistakes, but you trade fighting the type system and leaving in the actually hard bugs. (Space leaks in Haskell are definitely not fun.) Then there are the bugs introduced because of the development process, who has never had his program do something weird because you left in some stubs to keep the compiler happy. My pet theory is that a lot of that sentiment comes from starting out in C, where most of your time you sit in gdb (aka C interpreter) tracking down stupid mistakes. C++ trades that with spending most time pattern matching enormous template instantiation or pages-long type errors. I personally feel a lot more at ease in gradual type systems, you only add typing where and when you actually care.
|
# ? Nov 15, 2016 16:27 |
|
Beef posted:My pet theory is that a lot of that sentiment comes from starting out in C, where most of your time you sit in gdb (aka C interpreter) tracking down stupid mistakes. C++ trades that with spending most time pattern matching enormous template instantiation or pages-long type errors. I personally feel a lot more at ease in gradual type systems, you only add typing where and when you actually care.
|
# ? Nov 15, 2016 18:37 |
|
Beef posted:[] degenerates to pointer in a function call, but they are definitely not the same. Plus, if you care about performance, your compiler will thank you for using [] where appropriate instead of manually degenerating into pointer type everywhere. I skimmed it because it's super boring but it looks like this study suggests that static typing is "modestly better" than weak typing.
|
# ? Nov 16, 2016 06:35 |
|
nielsm posted:What you're after is probably a call graph. Various static analysis tools should be able to produce one. Which tool to get depends on what compiler/toolchain you're otherwise using. Thanks! That looks like what I want and it makes it much easier to google now that I know of a name for it. I've been using gcc (sometimes trying out clang) and msvc. Seems like you can get some dump out from gcc with "-fdump-rtl-expand" and then you can plot it with some tool like egypt but I have not tried this out yet.
|
# ? Nov 16, 2016 07:20 |
|
Hyvok posted:Thanks! That looks like what I want and it makes it much easier to google now that I know of a name for it. I've been using gcc (sometimes trying out clang) and msvc. Seems like you can get some dump out from gcc with "-fdump-rtl-expand" and then you can plot it with some tool like egypt but I have not tried this out yet. Note that you'll need to process the sources for your runtime libraries as well, if you want to see fully into possible allocations.
|
# ? Nov 16, 2016 14:52 |
|
Fergus Mac Roich posted:I skimmed it because it's super boring but it looks like this study suggests that static typing is "modestly better" than weak typing. That doesn't make sense. You can have weak static type systems and strong dynamic ones.
|
# ? Nov 16, 2016 20:17 |
|
Ralith posted:That doesn't make sense. You can have weak static type systems and strong dynamic ones. Sorry, that's my blunder, the term they use is strong typing, not static. What is a weak, static type system, though?
|
# ? Nov 17, 2016 01:41 |
|
Fergus Mac Roich posted:Sorry, that's my blunder, the term they use is strong typing, not static. What is a weak, static type system, though? Everyone mostly seems to agree these days that strong typing is obviously correct, since a crash is almost always preferable to silently doing the wrong thing, but there's still a lot of people clinging to dynamic (but strong) type systems.
|
# ? Nov 17, 2016 02:00 |
|
Fergus Mac Roich posted:Sorry, that's my blunder, the term they use is strong typing, not static. What is a weak, static type system, though? C.
|
# ? Nov 17, 2016 03:25 |
|
Ralith posted:Everyone mostly seems to agree these days that strong typing is obviously correct, since a crash is almost always preferable to silently doing the wrong thing, but there's still a lot of people clinging to dynamic (but strong) type systems. (Which is why C++ is the best because you can template-wrap things to make specific pain-in-the-rear end casts do themselves.)
|
# ? Nov 17, 2016 03:29 |
|
roomforthetuna posted:A compile time error is always preferable to silently doing the wrong thing, and a crash is usually preferable to silently doing the wrong thing, but both comparisons are ignoring the fact that 99% of the time weak typing silently does the right thing, and it's a time-consuming pain in the rear end to explicitly cast things every time you want to use them as something else.
|
# ? Nov 17, 2016 03:53 |
|
Ralith posted:Why are you constantly trying to pretend values have a type they don't?
|
# ? Nov 17, 2016 04:03 |
|
"I constantly need to convert values to different types" is a problem that most other people don't seem to have. So we're wondering what you're actually doing that's causing it to be so painful for you. Really the only thing I can think of is a poorly-designed api that has you downcasting things all over the place, in which case the solution isn't "weak typing", the solution is "un-gently caress the api".
|
# ? Nov 17, 2016 04:12 |
|
Jabor posted:"I constantly need to convert values to different types" is a problem that most other people don't seem to have. So we're wondering what you're actually doing that's causing it to be so painful for you. int/double?
|
# ? Nov 17, 2016 04:20 |
|
Subjunctive posted:int/double?
|
# ? Nov 17, 2016 08:23 |
I routinely cast floats to doubles and vice versa if I need more precision for a pre-processing step of some description, but float is fine for whatever I use them for after. Also sometimes ints to floats before uploading data to the GPU for use with OpenGL. Those kinds of casts do have their uses, and if you're working with any kind of low-level API that relies on specific data specifications, working without these kinds of things is a pain in the rear end.
Joda fucked around with this message at 09:22 on Nov 17, 2016 |
|
# ? Nov 17, 2016 09:19 |
|
Jabor posted:"I constantly need to convert values to different types" is a problem that most other people don't seem to have. So we're wondering what you're actually doing that's causing it to be so painful for you. If people typically don't need to convert values between types then surely it makes absolutely no difference whether you have strong/weak/static/dynamic/whatever typing, so the topic is completely uninteresting. Also, surely I'm not the only one who often wants to convert things to strings!
|
# ? Nov 18, 2016 03:40 |
|
roomforthetuna posted:If people typically don't need to convert values between types then surely it makes absolutely no difference whether you have strong/weak/static/dynamic/whatever typing, so the topic is completely uninteresting. It absolutely makes a difference, because the point of strong typing is so that you don't unintentionally end up doing type conversions that are inappropriate/introduce hard-to-diagnose bugs/are just plain silly. You're right that the topic is uninteresting though, it's not interesting specifically because there's one obviously correct answer.
|
# ? Nov 18, 2016 03:49 |
|
roomforthetuna posted:Also, surely I'm not the only one who often wants to convert things to strings! Even when that functionality is available, since you're dealing with something that explicitly consumes whatever type and produces a string, the interface ends up looking about the same as it would in a language with a sane type system anyway. Ralith fucked around with this message at 04:18 on Nov 18, 2016 |
# ? Nov 18, 2016 04:15 |
|
Ralith posted:I almost never want to "convert things to strings." I occasionally want to produce some particular human-oriented text view of a value, but this is both a very small proportion of the code I write and represents a specific set of requirements which varies significantly from case to case. Languages which expect you to just pretend everything's a string can be frustrating here above and beyond being inherently prone to a wide variety of bugs, because they often neglect to provide any of the fine formatting control you need to produce good human-readable forms of data. Reimplementing functionality that C had decades ago is not my idea of a good time. How about adding integers of different size/signedness?
|
# ? Nov 18, 2016 06:31 |
b0lt posted:How about adding integers of different size/signedness? I might be in the minority here, but I think that should also require an explicit cast. Rust /Haskell get this right IMO.
|
|
# ? Nov 18, 2016 06:47 |
|
b0lt posted:How about adding integers of different size/signedness?
|
# ? Nov 18, 2016 19:10 |
|
I want to automatically generate minimal boolean expressions for the control signals coming out of an instruction decoder. The inputs to this algorithm are a table of all instructions and the corresponding control signals they need to set. What's a good way to approach this kind of problem? A giant karnaugh map? I'd also like zero redundancy in the expressions to minimise the size of the decoder.
|
# ? Nov 26, 2016 16:58 |
|
Spatial posted:I want to automatically generate minimal boolean expressions for the control signals coming out of an instruction decoder. The inputs to this algorithm are a table of all instructions and the corresponding control signals they need to set. That's a hard problem. https://en.wikipedia.org/wiki/Espresso_heuristic_logic_minimizer
|
# ? Nov 26, 2016 20:51 |
|
|
# ? Jun 8, 2024 02:43 |
|
I am using in one of my projects the crow http library (https://github.com/ipkn/crow) . My compiler (gcc 6.2.1) is complaining about this code from the library:code:
How should the 2 byte network to host conversion be done to avoid that warning and still be correct?
|
# ? Dec 4, 2016 01:42 |