|
POD?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
Plain Old Data.
usually simple types like int, char, float...
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
It appears to me that you may be doing much programming that doesn't really fit into a strong, static typing world. Maybe a dynamically typed language, with any variable having the type of its value (at any time) would suit your problems better.
I love the strictness of strong static typing. It makes it possible for the compiler to give me far more detailed and to-the-point error messages and warnings. When reading the code, it provides more information, making it simpler to comprehend the code.
There are situations where auto/var is required, e.g. in database operations; I am not objecting to using in in such cases. In most cases, you can extract the values to strongly typed variables. I do not leave them in untyped variables for long.
Corollary, I try to avoid deep subclass nesting. Choosing between having to inspect 4-6 superclass definitions to find the definition of a field (hopefully with a comment explaining its use) or extending a superclass with a field that for some instances are left unused, I definitely prefer the latter. (I have many times seen subclasses created for adding a single field - even with several sibling classes adding the same single field!)
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
I think you're confusing things up.
C++ is still strongly typed even when you use auto.
when I declare a variable with auto, it will be typed accordingly and I cannot change the type.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Maximilien wrote: when I declare a variable with auto, it will be typed accordingly and I cannot change the type.
Err...in C++?
Rather certain you can in fact change the type. Not generally a good idea but one can certainly do it.
char* s = ....;
int* p = (int*)s;
I have seen very limited situations where it provided value.
|
|
|
|
|
That's a C -like dirty hack. Useful at times.
There are also union s and variant s. Nonetheless C++ remains a strong typed programming language.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
That does not change anything, it's a cast. It merely tells the compiler "even though s is a char* , for this statement only, pretend it points to an int .
|
|
|
|
|
I believe that in terms of the semantic functionality that the type is now changed.
If you have a method that takes the second type, the compiler will complain if you pass the first but not the second.
I have in fact used a char array as a integer before. At least in that case there was no definable difference between the two.
So exactly, in terms of the language, how does the cast not make it into a different type?
|
|
|
|
|
Well, think of it this way: What is a type? What do we mean when we declare the type of a variable?
We're declaring how we want the compiler to treat the data value. It's not an existential property of the variable, it's the way that we interpret the value.
So:
char* b = "ABCD"; And:
int* a = (int*)b; We're declaring an action, not a property of the variable.
The difficult we do right away...
...the impossible takes slightly longer.
modified yesterday.
|
|
|
|
|
A char* is in reality just an index into a portion of memory. So at the machine level it has no type-ness, it can be used to address anything from a byte to a quadword. But as far as the language is concerned it only ever points to a character. When you use a cast the compiler does what can be done at machine level, but the object itself is still a char* , and any attempt to use it in any other way will raise a compiler error. If you have something like the following:
int somefunction(int* pi, int count)
{
int sum = 0;
for (int i = 0; i < count; ++i)
{
sum += *pi;
}
return sum;
}
char* ci = "Foobar";
int total = somefunction((int*)ci, strlen(ci));
The type of ci does not change at all, it is just that its value is passed to somefunction , as the cast allows you to break or ignore the rules of the language. And the result of calling that function may, or may not, make sense.
|
|
|
|
|
In your example, it should be noted that if the target CPU requires that an int have, for example, an even byte alignment, you may get an exception when trying to dereference the int pointer.
I also wondered if you meant to increment the int pointer inside the loop, in which case, at some point you would invoke undefined behavior. Unless, of course, sizeof(int) == sizeof(char) . Which isn't impossible, but I don't know of any system where that might be true. Maybe a 6502 or other 8bit system?
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
k5054 wrote: if the target CPU ... True, but hardly relevant to the point I was trying to make.
And yes, I should have incremented the integer pointer - writing (poor) code in a hurry.
|
|
|
|
|
In my world - close to hardware - it's important to know and understand the type. Sure, if I'm using a modern IDE with Intellisense (only one comes to mind) auto might help. But, because of the proximity to hardware, we really don't use complex C++ types. Shoot, the last time I tried to use a C++ map, it was 10x slower than a simple linear search loop. I did not believe it at first...
But getting back to using auto with it's intellisense interaction, intellisense does it's thing for plain and complex types as well. I'm not sure what the point it (other than reduced typing).
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
As already mentioned in several answers, auto keyword doesn't make C++ code less strong-typed or type-safe. So, using auto is individual preference. In some cases (such as templates, lambda) there is no other choice.
When auto is optional, I always use it for complicated types, like container iterators. I also like auto in container enumeration code:
for(const auto& x: my_container)
{
}
As for local variables, it depends. Sometimes we want the variable to have another type. If the variable must have the same type, as expression, auto can help, when the code is changed:
std::vector<short> v;
short n = v[0];
Consider the situation, when we change the container type to int:
std::vector<int> v;
short n1 = v[0]; auto n2 = v[0]; decltype(v)::value_type n3 = v[0];
I find myself using auto more and more. Sometimes, when I want to see exactly, what I am doing, I prefer to use an explicit type.
|
|
|
|
|
I clearly have a limited understanding of C++. I admittedly come from a C background, and I have embraced the general concepts of C++ (most of the 4 pillars). But I'm going to be honest here
It seems to me that auto is fixing or making easier to use some of the more spurious features of C++. Just a general thought, but it gets back to my original post/question. For example, your comment: "decltype(v)::value_type n3 = v[0];" means absolutely nothing to me. I'm at the level of wtf?
So, I went out to the internet and read: "Inspects the declared type of an entity or the type and value category of an expression." for decltype. I still don't know what that means. Are we off in the top 0.01% land of coding? It's okay, I found my niche long ago, but seriously, it feels like so many special features have been added that only apply to the religious fanatics of code land.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
I also prefer C over C++, and decltype example was kind of joke. Bad joke, I guess. In any case:
decltype(v) means: type of v variable, vector of int in this case. vector type has value_type typedef, defined as T, see here: std::vector - cppreference.com[^]
So, this ridiculous (for anyone, except C++ snobs) line is translated by compiler to int, i.e. vector template parameter.
|
|
|
|
|
(for anyone, except C++ snobs)
Now I need to clean my screen - just spit all over it laughing. honestly, I did make the comment that there are people out there that code at a level I cannot even comprehend. I've come to call them "code witches" <--- I'm waiting to see if anyone follows the reference I read your description of what decltype does and I think, "hmm, I need to pass gas."
It's almost like some of the new "features" and auto is not new - 2010 ish raise areas of C++ to a meta programming language on it's own. Macros on steroids or something.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
Maybe someone can point me to a reference or provide direct experience. I'm trying to lift a VC6++ application to VS2022. Originally targeted at Xp, this will need to run under Win10 and 11. So, I thought it would also be a good idea to get it into a modern development environment.
Well, the # of warnings I am suppressing is getting concerning, but I understand what the warnings are about. Then I ran into this line of code:
"ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)"
pure mfc macro which generates "....cpp(66): warning C26454: Arithmetic overflow: '-' operation produces a negative unsigned result at compile time (io.5)."
Mousing over the macro, it expands to some hideous expression: "{ 0x004E + 0xBC00, (WORD)(int)((0U - 0U) - 12), 0, 0, AfxSigNotify_v, (AFX_PMSG)(static_cast<void (ccmdtarget::*)(nmhdr*,="" lresult*)=""> (OnCustomDraw)) },"
It's clear why the compiler is alarmed: "(WORD)(int)((0U - 0U) - 12)"
Am I just wasting my time here? I'm going to thunder on, but I'm starting to wonder if I'm going to run into so much nonsense like this that it calls into question if I'll have anything working at the end....
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
charlieg wrote: Then I ran into this line of code:
"ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)"
pure mfc macro which generates "....cpp(66): warning C26454: Arithmetic overflow: '-' operation produces a negative unsigned result at compile time (io.5)."
Mousing over the macro, it expands to some hideous expression: "{ 0x004E + 0xBC00, (WORD)(int)((0U - 0U) - 12), 0, 0, AfxSigNotify_v, (AFX_PMSG)(static_cast<void (ccmdtarget::)(nmhdr,="" lresult*)=""> (OnCustomDraw)) },"
It's clear why the compiler is alarmed: "(WORD)(int)((0U - 0U) - 12)"
Am I just wasting my time here? I'm going to thunder on, but I'm starting to wonder if I'm going to run into so much nonsense like this that it calls into question if I'll have anything working at the end....
1. It's not a compiler but IntelliSense alarm.
2. Yes, you are just wasting your time here. Just don't worry if the real compiling doe not show it as an error.
|
|
|
|
|
thank you.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
"Waste of time"?
If you're having fun doing this I'd say it's never a waste of time (doing this). That said, I'm reading WORD and thinking "If I ever get back into developing that QBASIC code (of mine) in that project in C++ where I've already got executable stubbs of function tests (vastly complex mathematical calculations made in lengthy formulas (astronomical in the sense of astronomy itself)) pasted into the VS interface, line numbers included (before QBASIC includes!), I'll probably have to go through MFC VC6++ in the stackoverload and codeguru websites to do the conversions and encounter this very issue".
Do you mean DWORD? I think I get "0U" ...
I'll fire up VS now, sir ... (firing up vs now) ... "C26454" ... uhm ... hangon ...
|
|
|
|
|
I think something was mangled in the translation. I took: "Yes, you are just wasting your time here. Just don't worry if the real compiling does not show it as an error." which I took to mean not fret about the warning.
I really need to lift this code, and working with VS2022 is "interesting." I've never seen a compiler generate so many arcane errors due to a typo. At the moment, I am trying to figure out why VS2022 is upset with '_messageEntries': const object must be initialized. It really has nothing to do with _messageEntries (this is an MFC thing) but more to with an error a few lines up.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
Ok, sorry about that. I just stoked up VS2022 and looking in the help found the WORD initializer. Who knew? Although I guess I was on a "Joan of Arcadia" type of bender in my sarcastic musing, I've since settled on refraining from CP commenting for my own good and am turning over this new leaf by announcing it here in the C/C++/MFC forum where there's probably less of an iota of confusion not of my own making.
Tyll should be good. Again, sorry.
|
|
|
|
|
it's been a loooonnnggg time since I converted/upgraded a MFC application.
If I remember correctly, signature changed for a lot of MFC messages and callback functions.
you need to check the documentation for each of those messages.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
tracked down the one thing that was plaguing me.
Documentation? f***, all I can find are useless Microsoft help articles that are just informational to the point of flying you into the mountain. Return me to the days of DEC, where one bookcase help the complete knowledge.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|