Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
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

Adbot
ADBOT LOVES YOU

BigRedDot
Mar 6, 2008

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.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
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.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

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.
That is, however, purely a matter of syntax. It's still part of the type.

Xarn
Jun 26, 2015

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 :shrug:

(Modern C++ is still my preferred language though :v:)

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.

Also this is most likely undefined as gently caress.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)

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 :shrug:

(Modern C++ is still my preferred language though :v:)

Also this is most likely undefined as gently caress.

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 :getin:

Xarn
Jun 26, 2015

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?

If I had it my way, we'd only have the types wire and reg :getin:

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 :getin: (Ok, I only saw that once :v:)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
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.

Klades
Sep 8, 2011

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.

feedmegin
Jul 30, 2008

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.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

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.

raminasi
Jan 25, 2005

a last drink with no ice

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.

eth0.n
Jun 1, 2012

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.

Hyvok
Mar 30, 2010
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?

nielsm
Jun 1, 2009



Hyvok posted:

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?

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.

Beef
Jul 26, 2004

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.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

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.
You know that most advanced type systems are vastly easier to work with than that of C++, right?

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

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 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.

I skimmed it because it's super boring but it looks like this study suggests that static typing is "modestly better" than weak typing.

Hyvok
Mar 30, 2010

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.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

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.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

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.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

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?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

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?
I'm not sure there are any complete real-world systems that have been built that way, because if you've realized static typing is a good idea you can probably work out that weak typing is pretty dumb, but numbers in C/C++ can be reasonably described as both statically and weakly typed. Any given variable or expression has a particular type, but you can use values of one type in a location that expects another and the implementation silently does its best to guess what you meant.

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.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

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.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

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.
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.

(Which is why C++ is the best because you can template-wrap things to make specific pain-in-the-rear end casts do themselves.)

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

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.

(Which is why C++ is the best because you can template-wrap things to make specific pain-in-the-rear end casts do themselves.)
Why are you constantly trying to pretend values have a type they don't?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Ralith posted:

Why are you constantly trying to pretend values have a type they don't?
Why do you always reply to my things with a vague question that seems almost completely unrelated to what I said?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
"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".

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

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?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Subjunctive posted:

int/double?
Are very different kinds of things usually best used in very different places for very different reasons. Various bugs are routinely caused by people forgetting this.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
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

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

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.
Ah, thanks for translating! I don't think that's a thing that I say all that much, maybe I'm being conflated with someone else? I was talking in the abstract about different type systems this last time, so it had nothing to do with me needing to convert anything to anything.

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!

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

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.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

roomforthetuna posted:

Also, surely I'm not the only one who often wants to convert things to strings!
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.

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

b0lt
Apr 29, 2005

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.

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.

How about adding integers of different size/signedness?

VikingofRock
Aug 24, 2008




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.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

b0lt posted:

How about adding integers of different size/signedness?
Playing "guess the overflow hazard" isn't my idea of a good time either. The wide array of implicit conversions that can happen are not intuitive. Given polymorphic literals, you'll find that doing that sort of thing comes up far less than you might expect anyway.

Spatial
Nov 15, 2007

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.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

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.

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.

That's a hard problem.

https://en.wikipedia.org/wiki/Espresso_heuristic_logic_minimizer

Adbot
ADBOT LOVES YOU

Volguus
Mar 3, 2009
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:
uint64_t remaining_length_{0};

....//reading 2 bytes from the network....

remaining_length_ = ntohs(*(uint16_t*)&remaining_length_);
Warning given: "warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]"

How should the 2 byte network to host conversion be done to avoid that warning and still be correct?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply