Old 08-25-2017, 05:41 AM   #1
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default C++17

Just about to start coding the Control Surface Integrator, anyone know of a reason(s) why I should use/not use C++17 compilers for the project ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 08-25-2017, 06:37 AM   #2
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Reasons why you might not want to use it (or even C++11 compatible compilers) :

1) If you need to support ancient macOS-X versions. macOS-X 10.7 is the first one to have support for C++11. (More precisely, support for the C++11 standard library.) Newer C++ standards might require even later macOS versions.
2) If you need to support Windows XP. I have never got the so called "Windows XP compatibility" working with the newer Visual Studio versions. (Like VS2015 or VS2017.) The resulting binaries simply have not worked on XP for me or for people who have tried to test the binaries. It might work if the end user Windows XP installation is completely up to date with SP3 and all possible updates. I never bothered testing that scenario myself.
3) The Microsoft C++ compiler and standard library and Apple's compiler/library are not at the same level of standard compliance. If you write code that compiles for macOs, it might not work with the Microsoft compiler and vice versa. So you need to be careful which language and standard library features you use. Both platforms have good, but not complete, C++11/14 coverage now, though.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 08-25-2017 at 06:44 AM.
Xenakios is offline   Reply With Quote
Old 08-26-2017, 12:10 PM   #3
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

As usual, good points, thanks Xen.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 08-26-2017, 04:54 PM   #4
Garrick
Human being with feelings
 
Garrick's Avatar
 
Join Date: Jul 2009
Location: Wellington
Posts: 4,622
Default

Do any of you guys use "auto" for your types?

It feels wrong to me somehow
Garrick is offline   Reply With Quote
Old 08-26-2017, 05:05 PM   #5
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by Garrick View Post
Do any of you guys use "auto" for your types?

It feels wrong to me somehow
I grew up on a curious mix, assembly, C, and Smalltalk.

So, hell yeah, I'll be using auto wherever I can
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 08-26-2017, 05:22 PM   #6
Garrick
Human being with feelings
 
Garrick's Avatar
 
Join Date: Jul 2009
Location: Wellington
Posts: 4,622
Default

Quote:
Originally Posted by Geoff Waddington View Post
I grew up on a curious mix, assembly, C, and Smalltalk.

So, hell yeah, I'll be using auto wherever I can
Assembly infers type? Is there no end to this madness.
Well that shows how much I know. I thought assembly would be super dupa strict and make you be explicit about everything.

Last edited by Garrick; 08-26-2017 at 05:27 PM.
Garrick is offline   Reply With Quote
Old 08-26-2017, 06:17 PM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Garrick View Post
Do any of you guys use "auto" for your types?

It feels wrong to me somehow
It's highly debatable if "auto" is that useful for trivial stuff like integer or floating point types, but it's clearly useful when more complicated types are involved. For example, do you want to write

Code:
std::unique_ptr<MyFancyObject<String>> o = std::make_unique<MyFancyObject<String>>("foo");
or would you prefer

Code:
auto o = std::make_unique<MyFancyObject<String>>("foo");
?

And yeah, I do use "auto" regularly.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 08-26-2017 at 06:44 PM.
Xenakios is offline   Reply With Quote
Old 08-26-2017, 10:05 PM   #8
Garrick
Human being with feelings
 
Garrick's Avatar
 
Join Date: Jul 2009
Location: Wellington
Posts: 4,622
Default

Quote:
Originally Posted by Xenakios View Post
It's highly debatable if "auto" is that useful for trivial stuff like integer or floating point types, but it's clearly useful when more complicated types are involved. For example, do you want to write

Code:
std::unique_ptr<MyFancyObject<String>> o = std::make_unique<MyFancyObject<String>>("foo");
or would you prefer

Code:
auto o = std::make_unique<MyFancyObject<String>>("foo");
?

And yeah, I do use "auto" regularly.
Whoa !!
Yeah I can see now how auto could be a godsend.

Especially in your example where your fancy object's name will pretty much document itself and so easier to reason about.

This is good, it's making me re-think the whole thing.

Like you say, it has limited usefulness with primitives, but if you did, how do you cast from one type to another if you're not explicit what type it originally was?
Garrick is offline   Reply With Quote
Old 08-27-2017, 03:57 AM   #9
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by Garrick View Post
Assembly infers type? Is there no end to this madness.
Well that shows how much I know. I thought assembly would be super dupa strict and make you be explicit about everything.
Haha, I more meant Smalltalk, but you got me thinking about this

In a way assembly does have a notion something like type deduction sometimes, here's an example of what I mean.

In our old quirky friend Intel 8088 we can say something like:

Mov AL, SUM // where AL is the lower half (8 bits) of AX therefore 1 byte is moved

Mov AX, SUM // where AX is the whole 16 bit register therefore 2 bytes are moved.

Now, this isn't really typing, you can treat the 8 bits in AL as a character, set of bit flags, or any other data type, and similar for the 16 bits in AX.

So in a way there is some notion of types in at least some assemblers.

Other than that assembler (in vonNeumann architecture processors) is the opposite of strict, it allows you to point to any memory location and treat it as a value, a pointer, code that can be executed, or anything else you can dream up.

Assembly is an extremely powerful and dangerous place, the wild west of anarchy, if you will, no restrictions whatsoever
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 08-27-2017, 06:51 AM   #10
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Garrick View Post
how do you cast from one type to another if you're not explicit what type it originally was?
Basically just like one normally would, since casting usually requires just the new destination type to be written out in the code. The compiler obviously knows all the time what the original type is. ("auto" is completely a compile time thing.)

If the cast destination type needs to be determined from an "auto" type variable, that's also possible to do, with "decltype".

So nonsense like this is possible but probably never useful with primitive types :
Code:
auto intnumber = 777;
auto destnumber = 0.5;
auto cast_number = static_cast<decltype(destnumber)>(intnumber);
A much more useful example of "auto" usage, which couldn't even be written without "auto" if one wishes to keep the functions as C++11 lambdas for as long as possible :

Code:
auto make_mapping_functions(float minv, float maxv, float middleval)
{
	auto normtovaluefunc = [minv,maxv,middleval](float, float, float normval)
	{
		if (normval<0.5f)
			return jmap(normval, 0.0f, 0.5f, minv, middleval);
		else return jmap(normval, 0.5f, 1.0f, middleval, maxv);
	};
	auto valuetonormfunc = [minv,maxv,middleval](float, float, float val)
	{
		if (val < middleval)
			return jmap(val, minv, middleval, 0.0f, 0.5f);
		else return jmap(val, middleval, maxv, 0.5f, 1.0f);
	};
	return std::make_pair(normtovaluefunc, valuetonormfunc);
}
// usage :
auto mapfuncs = make_mapping_functions(0.1f, 10.0f, 1.0f);
NormalisableRange<float> prrange(0.1f, 10.0f, mapfuncs.first, mapfuncs.second);
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 08-27-2017 at 08:22 AM.
Xenakios is offline   Reply With Quote
Old 08-28-2017, 02:41 AM   #11
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by Xenakios View Post
Basically just like one normally would, since casting usually requires just the new destination type to be written out in the code. The compiler obviously knows all the time what the original type is. ("auto" is completely a compile time thing.)

If the cast destination type needs to be determined from an "auto" type variable, that's also possible to do, with "decltype".

So nonsense like this is possible but probably never useful with primitive types :
Code:
auto intnumber = 777;
auto destnumber = 0.5;
auto cast_number = static_cast<decltype(destnumber)>(intnumber);
A much more useful example of "auto" usage, which couldn't even be written without "auto" if one wishes to keep the functions as C++11 lambdas for as long as possible :

Code:
auto make_mapping_functions(float minv, float maxv, float middleval)
{
	auto normtovaluefunc = [minv,maxv,middleval](float, float, float normval)
	{
		if (normval<0.5f)
			return jmap(normval, 0.0f, 0.5f, minv, middleval);
		else return jmap(normval, 0.5f, 1.0f, middleval, maxv);
	};
	auto valuetonormfunc = [minv,maxv,middleval](float, float, float val)
	{
		if (val < middleval)
			return jmap(val, minv, middleval, 0.0f, 0.5f);
		else return jmap(val, middleval, maxv, 0.5f, 1.0f);
	};
	return std::make_pair(normtovaluefunc, valuetonormfunc);
}
// usage :
auto mapfuncs = make_mapping_functions(0.1f, 10.0f, 1.0f);
NormalisableRange<float> prrange(0.1f, 10.0f, mapfuncs.first, mapfuncs.second);
Nice !!

I've got Scott Meyers Effective Modern C++ and, of course, a ton of web resources.

Any particular resources you think would help an old C veteran with the strange additions of assembly and Smalltalk get up to speed on modern C++ ?

Closures/lambdas are called blocks in Smalltalk and they are highly powerful and super handy as in C++, so I get the lambdas thing.

Everyone is pushing the reasons to use constexpr and that's cool.

Just getting into Jason Turner's C++ Weekly vids.

So, veteran OO programmer, newly converting to modern C++.

Thanks for any help.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 08-28-2017, 07:37 AM   #12
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Geoff Waddington View Post
Any particular resources you think would help an old C veteran with the strange additions of assembly and Smalltalk get up to speed on modern C++ ?

Everyone is pushing the reasons to use constexpr and that's cool.
https://isocpp.org/ sometimes has interesting links.

constexpr stuff is cool if it happens to work, but I personally haven't spent much effort in making things compatible with that. So much stuff just has to happen at runtime, after all...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 09-05-2017, 11:12 PM   #13
Kyran
Human being with feelings
 
Join Date: Sep 2010
Posts: 49
Default

Also check out CPPcon and BoostCon on Youtube. They publish videos of their conference lectures, many of which are focused around modern, idiomatic C++. I usually change the playspeed to 1.5x or 2x unless someone's a particularly quick speaker. That way it doesn't take so much time to sit through a talk. You could spend months watching videos and not run out of content.

The CPP subreddit tends to have pretty decent content as well.

It's probably really difficult to come up to speed since most modern tutorials will assume knowledge of older C++, but some of that older C++ is obsolete or bad practice. If you're looking for a book that teaches modern C++ (C++14) while also covering a lot of fundamentals, this one might be good.


Quote:
Originally Posted by Xenakios View Post
So much stuff just has to happen at runtime, after all...
The best part about constexpr functions is they can be used at compile time or run time, depending on the context in which they're evaluated. With the more relaxed rules of C++17, a lot of times you can slap a constexpr on an existing runtime function and have it work at compile time for free.
Kyran is offline   Reply With Quote
Old 09-08-2017, 10:00 AM   #14
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Just one example about what I like about just C++11, it's possible to quite trivially make functions that are essentially just for loops with a descriptive name :
Code:
    template<typename F>
    void for_each_selected_zone(F&& func, bool usemutex=false)
    {
		for (auto& e : m_selected_zones)
		{
			if (usemutex)
				processor.m_mutex.lock();
			func(processor.getSamplerSound(e));
			if (usemutex)
				processor.m_mutex.unlock();
		}
    }

// usage :

for_each_selected_zone([this](XenSamplerSound* snd)
{
  snd->m_num_outchans = m_numoutchanscombo.getSelectedId() - 1;
},true);
IMHO this can really reduce the chances of making a mistake while writing the iteration code.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 09-08-2017 at 10:12 AM.
Xenakios is offline   Reply With Quote
Old 09-11-2017, 03:04 AM   #15
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Having some fun, having some frustration fighting with compiler on types, whilst learning good hygienic modern C++

Find myself typing 'const' an lot, maybe they should have made it the default and used the keyword 'unconst' instead

Talk about a breaking change !!
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:54 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.