Variadic console templates #1920

Merged
merged 13 commits into from Jan 13, 2017

Conversation

Projects
None yet
7 participants
@elfprince13
Contributor

elfprince13 commented Jan 7, 2017

Drastically improved the maintainability of the console API stuff. There are still two places with hardcoded array sizes preventing functions and methods of arbitrary arity from being exposed to the console, but code bloat has also been significantly reduced.

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Jan 7, 2017

Contributor

Wow, this looks really slick!

Contributor

Areloch commented Jan 7, 2017

Wow, this looks really slick!

@dottools

This comment has been minimized.

Show comment
Hide comment
@dottools

dottools Jan 7, 2017

You've been busy. Nice work.

dottools commented Jan 7, 2017

You've been busy. Nice work.

@rextimmy

This comment has been minimized.

Show comment
Hide comment
@rextimmy

rextimmy Jan 7, 2017

Contributor

Awesome work mate

Contributor

rextimmy commented Jan 7, 2017

Awesome work mate

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 7, 2017

Contributor
Contributor

elfprince13 commented Jan 7, 2017

@JeffProgrammer

This comment has been minimized.

Show comment
Hide comment
@JeffProgrammer

JeffProgrammer Jan 7, 2017

Contributor

woo woo! Thanks :D

Contributor

JeffProgrammer commented Jan 7, 2017

woo woo! Thanks :D

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 10, 2017

Contributor

http://i.imgur.com/wGaswE5.jpg there a missing converted file or two? VS2013 32 bit mode really, really doesn't like it.

Contributor

Azaezel commented Jan 10, 2017

http://i.imgur.com/wGaswE5.jpg there a missing converted file or two? VS2013 32 bit mode really, really doesn't like it.

@jamesu

This comment has been minimized.

Show comment
Hide comment
@jamesu

jamesu Jan 10, 2017

Contributor

Would've done this myself but variadic templates scare me ;)

Contributor

jamesu commented Jan 10, 2017

Would've done this myself but variadic templates scare me ;)

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 10, 2017

Contributor
Contributor

elfprince13 commented Jan 10, 2017

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 11, 2017

Contributor

Okay, so, a couple things stand out to me:
This error makes me think you don't have support for constexpr here? template<typename T> constexpr T nullAsType(){ return nullptr; }

And this one seems to have a similar root cause.

It might be fine to replace constexpr with const everywhere I used it, since I don't think I was computing anything crazy at compile-time.

Contributor

elfprince13 commented Jan 11, 2017

Okay, so, a couple things stand out to me:
This error makes me think you don't have support for constexpr here? template<typename T> constexpr T nullAsType(){ return nullptr; }

And this one seems to have a similar root cause.

It might be fine to replace constexpr with const everywhere I used it, since I don't think I was computing anything crazy at compile-time.

@rextimmy

This comment has been minimized.

Show comment
Hide comment
@rextimmy

rextimmy Jan 11, 2017

Contributor

From this table here https://msdn.microsoft.com/en-us/library/hh567368.aspx ... constexpr is only available in 2015 or later

Contributor

rextimmy commented Jan 11, 2017

From this table here https://msdn.microsoft.com/en-us/library/hh567368.aspx ... constexpr is only available in 2015 or later

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 11, 2017

Contributor

I'm amused that craziness like decltype and trailing returns are supported, but not "no really, this is a constant at compile-time". Anyway, I'll see what I can do about about getting rid of it.

Contributor

elfprince13 commented Jan 11, 2017

I'm amused that craziness like decltype and trailing returns are supported, but not "no really, this is a constant at compile-time". Anyway, I'll see what I can do about about getting rid of it.

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 11, 2017

Contributor

#if _MSC_VER < 1900
#define constexpr const
#endif
seems to be workin so far. kinda brute-forced it after tryin to find a common file to shove it in though (Not the face, not the face!)

Contributor

Azaezel commented Jan 11, 2017

#if _MSC_VER < 1900
#define constexpr const
#endif
seems to be workin so far. kinda brute-forced it after tryin to find a common file to shove it in though (Not the face, not the face!)

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 11, 2017

Contributor

None of the places I was using it turned out to be necessary. I did switch my nullAsType templated function to be inlined though, because there's really no need for a function-call overhead there, it's just a typesafe nullptr to allow the template arguments to be generated implicitly in a few places. Anyway, give the new commit a try and see how it goes.

Contributor

elfprince13 commented Jan 11, 2017

None of the places I was using it turned out to be necessary. I did switch my nullAsType templated function to be inlined though, because there's really no need for a function-call overhead there, it's just a typesafe nullptr to allow the template arguments to be generated implicitly in a few places. Anyway, give the new commit a try and see how it goes.

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 11, 2017

Contributor

compiles

Contributor

Azaezel commented Jan 11, 2017

compiles

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Jan 11, 2017

Contributor

Seems to run for me as well.

Wanna run it through the linux and mac gambut tomorrow before rolling it in, but it seems good so far.

Contributor

Areloch commented Jan 11, 2017

Seems to run for me as well.

Wanna run it through the linux and mac gambut tomorrow before rolling it in, but it seems good so far.

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Jan 12, 2017

Contributor

Checks out on mac. Just gotta finish my runthrough of it on the linux side.

Contributor

Areloch commented Jan 12, 2017

Checks out on mac. Just gotta finish my runthrough of it on the linux side.

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Jan 13, 2017

Contributor

And lin seems good :)

Contributor

Areloch commented Jan 13, 2017

And lin seems good :)

@Areloch Areloch merged commit 0c6174b into GarageGames:development Jan 13, 2017

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 17, 2017

Contributor

@elfprince13: If you've got a sec, finally had a chance to sync afx in. Seems to be a bit unhappy:

https://github.com/Azaezel/Torque3D/tree/afx_plus_devhead_boom

https://gist.github.com/Azaezel/59463541da088ca03078ea7dd740573b

edit: I assume examples like \Torque3D-AFX\Engine\source\console/engineFunctions.h(108) : see reference to function template instantiation 'std::tuple<_Ty &,const char &,const char &,SimObject &> &std::tuple<_Ty &,const char &,const char &,SimObject &>::operator =<int,int,int,int>(const std::tuple<int,int,int,int> &)' being compiled

for

DefineEngineFunction(startSelectron, S32, (SceneObject* selectedObj, unsigned int subcode, SimObject* extra),
(NULL, 0, NULL),
"Instantiates a selectron.\n\n"
"@InGroup AFX")

correlate to the nullAsType alts. (at least Azaezel@8ca53c7 seems to make the error reports go away)

less clear on

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), (arcaneFX::TARGET_CHECK_POLL),
"Push a new targeting-mode onto a statck of modes.\n\n"
"@InGroup AFX")

or what it's ranting about reguarding SuperType.

Contributor

Azaezel commented Jan 17, 2017

@elfprince13: If you've got a sec, finally had a chance to sync afx in. Seems to be a bit unhappy:

https://github.com/Azaezel/Torque3D/tree/afx_plus_devhead_boom

https://gist.github.com/Azaezel/59463541da088ca03078ea7dd740573b

edit: I assume examples like \Torque3D-AFX\Engine\source\console/engineFunctions.h(108) : see reference to function template instantiation 'std::tuple<_Ty &,const char &,const char &,SimObject &> &std::tuple<_Ty &,const char &,const char &,SimObject &>::operator =<int,int,int,int>(const std::tuple<int,int,int,int> &)' being compiled

for

DefineEngineFunction(startSelectron, S32, (SceneObject* selectedObj, unsigned int subcode, SimObject* extra),
(NULL, 0, NULL),
"Instantiates a selectron.\n\n"
"@InGroup AFX")

correlate to the nullAsType alts. (at least Azaezel@8ca53c7 seems to make the error reports go away)

less clear on

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), (arcaneFX::TARGET_CHECK_POLL),
"Push a new targeting-mode onto a statck of modes.\n\n"
"@InGroup AFX")

or what it's ranting about reguarding SuperType.

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

followup: the above commit +

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), (arcaneFX::TARGET_CHECK_POLL),

to

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), ((U32)arcaneFX::TARGETING_OFF, (U32)arcaneFX::TARGET_CHECK_POLL),

got her compilin at least, but is that the intended methodology for that style of case?

Contributor

Azaezel commented Jan 18, 2017

followup: the above commit +

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), (arcaneFX::TARGET_CHECK_POLL),

to

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), ((U32)arcaneFX::TARGETING_OFF, (U32)arcaneFX::TARGET_CHECK_POLL),

got her compilin at least, but is that the intended methodology for that style of case?

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), ((U32)arcaneFX::TARGET_CHECK_POLL), Should be sufficient, and have the same semantics as the original (i.e. no default argument for mode). For some reason the type inferencing is slightly more finicky now than it used to be, and doesn't pick up on available implicit conversions (e.g. nullptr_t -> SceneObject* or in your case, what I presume is an enum of some kind -> U32).

Your options are essentially

  • Explicit cast the default arguments to the required types (this is the nullAsType approach, and what you did here)
  • Add your enum type as an engine type and use that as the argument types (should be pretty trivial and is technically "safer")
  • Submit an improvement on my patch that handles implicit conversions.
Contributor

elfprince13 commented Jan 18, 2017

DefineEngineMethod(afxTSCtrl, pushTargetingMode, void, (unsigned int mode, unsigned int checkMethod), ((U32)arcaneFX::TARGET_CHECK_POLL), Should be sufficient, and have the same semantics as the original (i.e. no default argument for mode). For some reason the type inferencing is slightly more finicky now than it used to be, and doesn't pick up on available implicit conversions (e.g. nullptr_t -> SceneObject* or in your case, what I presume is an enum of some kind -> U32).

Your options are essentially

  • Explicit cast the default arguments to the required types (this is the nullAsType approach, and what you did here)
  • Add your enum type as an engine type and use that as the argument types (should be pretty trivial and is technically "safer")
  • Submit an improvement on my patch that handles implicit conversions.
@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

understood. will let other folk weigh in for a bit on preferences so we've got a standard for if that crops up with, say, the upcomming e/c work. thanks.

Contributor

Azaezel commented Jan 18, 2017

understood. will let other folk weigh in for a bit on preferences so we've got a standard for if that crops up with, say, the upcomming e/c work. thanks.

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

Actually, before I forget, you mentioned "and have the same semantics as the original (i.e. no default argument for mode)"

Had to do up:
f719731#diff-2379c816c502e2028ed3c3745b7c98b6

Precisely because only part of those fallbacks were being filled in and it was leading to uninitialized results. Yet another of those 'should probably take a mass run at this' PRs nobody, (and I admit fault here mself) has had time to follow up on.

May shed some light on some shenanigans.

Contributor

Azaezel commented Jan 18, 2017

Actually, before I forget, you mentioned "and have the same semantics as the original (i.e. no default argument for mode)"

Had to do up:
f719731#diff-2379c816c502e2028ed3c3745b7c98b6

Precisely because only part of those fallbacks were being filled in and it was leading to uninitialized results. Yet another of those 'should probably take a mass run at this' PRs nobody, (and I admit fault here mself) has had time to follow up on.

May shed some light on some shenanigans.

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

@Azaezel - I would think the better strategy would be to throw an error when too few arguments are given instead of relying on stored defaults that might not make any sense.

Contributor

elfprince13 commented Jan 18, 2017

@Azaezel - I would think the better strategy would be to throw an error when too few arguments are given instead of relying on stored defaults that might not make any sense.

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

@elfprince13 eh... I gotta say personally, I'm rather fond of being able to pull off stuff like
https://github.com/GarageGames/Torque3D/blob/development/Engine/source/T3D/aiPlayer.cpp#L1369
To my mind, it well represents Torque's philosophy to date of 'drop in a rough draft, and tweak it further if you need to'

That, and it's consistent with raw script methods, where you can feed it fewer than defined, and it'll fill in with blanks.

I'll admit, that does put the onus on us to correct cases as we find them, rather than a generalized solution.

Contributor

Azaezel commented Jan 18, 2017

@elfprince13 eh... I gotta say personally, I'm rather fond of being able to pull off stuff like
https://github.com/GarageGames/Torque3D/blob/development/Engine/source/T3D/aiPlayer.cpp#L1369
To my mind, it well represents Torque's philosophy to date of 'drop in a rough draft, and tweak it further if you need to'

That, and it's consistent with raw script methods, where you can feed it fewer than defined, and it'll fill in with blanks.

I'll admit, that does put the onus on us to correct cases as we find them, rather than a generalized solution.

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (nullAsType<ShapeBase*>(), 45.0f, false), imho, should be DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (45.0f, false), and an error should be raised if obj is missing as an argument. Nothing good can come of dereferencing a null pointer, and I'm generally of the opinion that TS's utility as a prototyping language is harmed by the frequency with which scripts are able to crash the engine without any diagnostic available to the scripter. Similarly in the earlier diff you linked, there's no reasonable use-case for asking the Filesystem to rename the empty string to anything at all, let alone using it as the destination. Default arguments are great where defaults are sensible (like fov and checkEnabled above), but only cause confusion where an argument should be required (and worse where leaving one out is going to blow something up in the engine state where a scripter can't see what's happening).

Contributor

elfprince13 commented Jan 18, 2017

DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (nullAsType<ShapeBase*>(), 45.0f, false), imho, should be DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (45.0f, false), and an error should be raised if obj is missing as an argument. Nothing good can come of dereferencing a null pointer, and I'm generally of the opinion that TS's utility as a prototyping language is harmed by the frequency with which scripts are able to crash the engine without any diagnostic available to the scripter. Similarly in the earlier diff you linked, there's no reasonable use-case for asking the Filesystem to rename the empty string to anything at all, let alone using it as the destination. Default arguments are great where defaults are sensible (like fov and checkEnabled above), but only cause confusion where an argument should be required (and worse where leaving one out is going to blow something up in the engine state where a scripter can't see what's happening).

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

Yeah, I can definitely see the need for tagging required with... just as a quick notion... dynamic_cast + errorf("variable %s was NULL!",methodtogetvarname), at a minimum, say? (Regardless of weather that is the default behavior when a value is not set as a fallback or not)

Have to admit, not entirely sure how that'd best be approached without a bit more digging this end at least...

Edit: or if you wanted it fatal-fatal, maybe somethin like https://github.com/GarageGames/Torque3D/pull/1286/files ?

Contributor

Azaezel commented Jan 18, 2017

Yeah, I can definitely see the need for tagging required with... just as a quick notion... dynamic_cast + errorf("variable %s was NULL!",methodtogetvarname), at a minimum, say? (Regardless of weather that is the default behavior when a value is not set as a fallback or not)

Have to admit, not entirely sure how that'd best be approached without a bit more digging this end at least...

Edit: or if you wanted it fatal-fatal, maybe somethin like https://github.com/GarageGames/Torque3D/pull/1286/files ?

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

The obvious thing is that _EngineFunctionDefaultArguments should store the index of the first default argument that is actually initialized using a call to sizeof...() in _EngineFunctionDefaultArguments::tailInit and engineAPI::detail::ThunkHelpers::getRealArgValue should complain loudly in the else-branch if index + method_offset is before that stored min-index.

The tricky part is how to propagate that error out to the console in a reasonable fashion (I don't particularly feel like implementing exceptions in TorqueScript and properly handling stack-unwinding...)

Contributor

elfprince13 commented Jan 18, 2017

The obvious thing is that _EngineFunctionDefaultArguments should store the index of the first default argument that is actually initialized using a call to sizeof...() in _EngineFunctionDefaultArguments::tailInit and engineAPI::detail::ThunkHelpers::getRealArgValue should complain loudly in the else-branch if index + method_offset is before that stored min-index.

The tricky part is how to propagate that error out to the console in a reasonable fashion (I don't particularly feel like implementing exceptions in TorqueScript and properly handling stack-unwinding...)

@Azaezel

This comment has been minimized.

Show comment
Hide comment
@Azaezel

Azaezel Jan 18, 2017

Contributor

For clarity for folks playing the home game, subconversation at this point involves how best to handle

(A,B,C)(fallbackA,fallbacB,fallbackC) vs (A,B,C)(fallbacB,fallbackC) (the latter may be documented to work, but empirical testing shows it breaks things)

both in the context of required, and optional parameters.

Contributor

Azaezel commented Jan 18, 2017

For clarity for folks playing the home game, subconversation at this point involves how best to handle

(A,B,C)(fallbackA,fallbacB,fallbackC) vs (A,B,C)(fallbacB,fallbackC) (the latter may be documented to work, but empirical testing shows it breaks things)

both in the context of required, and optional parameters.

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

The easiest thing might just be to add an AssertFatal (or even AssertISV depending on your intended audience), so that if the engine crashes afterwards at least they know why...

Contributor

elfprince13 commented Jan 18, 2017

The easiest thing might just be to add an AssertFatal (or even AssertISV depending on your intended audience), so that if the engine crashes afterwards at least they know why...

@jamesu

This comment has been minimized.

Show comment
Hide comment
@jamesu

jamesu Jan 18, 2017

Contributor

My thoughts:

Traditionally in TS you've been able to have a variable number of args to any function (up to the max in the stringstack). This helps a lot in some cases as you don't necessarily need to provide every arg to a function, and i'd bet most current TS probably doesn't use up every arg in every function, and you likely risk breaking code by changing this basic assumption.

TS itself has basic error handling for object creation errors (i.e. jump to location X) but beyond that no exceptions. If you want to implement proper exceptions in TS you'd probably be better off rewriting the scripting interpreter as the current one is quite hairy already. I myself have experimented with a rewrite of the TS code ( see https://github.com/jamesu/Torque2D/tree/twistscript ), but haven't implemented exceptions as stack unwinding through the C bridge is a bit of an issue. This also tends to be a bit hairy in other embeddable languages too from what i've seen (e.g. cleanup of local stack vars can be iffy).

Printing errors to the console is nice but experience I'd say there is a point where printing stuff in the console becomes useless as there is simply too much trash printed which cannot easily be filtered. This is an area in which T3D could do with a significant improvement (e.g. actually using log categories, adding extra metadata, filtering output, etc).

Contributor

jamesu commented Jan 18, 2017

My thoughts:

Traditionally in TS you've been able to have a variable number of args to any function (up to the max in the stringstack). This helps a lot in some cases as you don't necessarily need to provide every arg to a function, and i'd bet most current TS probably doesn't use up every arg in every function, and you likely risk breaking code by changing this basic assumption.

TS itself has basic error handling for object creation errors (i.e. jump to location X) but beyond that no exceptions. If you want to implement proper exceptions in TS you'd probably be better off rewriting the scripting interpreter as the current one is quite hairy already. I myself have experimented with a rewrite of the TS code ( see https://github.com/jamesu/Torque2D/tree/twistscript ), but haven't implemented exceptions as stack unwinding through the C bridge is a bit of an issue. This also tends to be a bit hairy in other embeddable languages too from what i've seen (e.g. cleanup of local stack vars can be iffy).

Printing errors to the console is nice but experience I'd say there is a point where printing stuff in the console becomes useless as there is simply too much trash printed which cannot easily be filtered. This is an area in which T3D could do with a significant improvement (e.g. actually using log categories, adding extra metadata, filtering output, etc).

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Jan 18, 2017

Contributor

James - I'm not complaining about the basic idea of having optional arguments, just the idea that all arguments should be optional and have sane defaults: there is no sane default to a Filesystem rename operation, or for most pointer dereferences. In cases where crashing the engine is likely to result from an unsupplied argument, the engine should at the very least say something about it first, and 95% of the machinery to handle that is in place, because the current engine API supports initializing fewer defaults than the total number of arguments used by the function.

Contributor

elfprince13 commented Jan 18, 2017

James - I'm not complaining about the basic idea of having optional arguments, just the idea that all arguments should be optional and have sane defaults: there is no sane default to a Filesystem rename operation, or for most pointer dereferences. In cases where crashing the engine is likely to result from an unsupplied argument, the engine should at the very least say something about it first, and 95% of the machinery to handle that is in place, because the current engine API supports initializing fewer defaults than the total number of arguments used by the function.

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Apr 3, 2017

Contributor

I don't know that it's specifically related, but at minimum, you're more familiar with the template voodoo than I am elf, so I figured i'd throw this in here as it may be sorta-associated. Mainly, VS2017 has an unpleasant bug that's causing some issues with compiling at the moment, as seen by this one post I found here:

https://developercommunity.visualstudio.com/content/problem/25618/visual-studio-2017-template-issues.html

The one guy provides a possible workaround to 'make it behave like VS2015', but I'm not sure how to utilize his example or what the implications are. Any chance you may have an idea of what's going on there?

Contributor

Areloch commented Apr 3, 2017

I don't know that it's specifically related, but at minimum, you're more familiar with the template voodoo than I am elf, so I figured i'd throw this in here as it may be sorta-associated. Mainly, VS2017 has an unpleasant bug that's causing some issues with compiling at the moment, as seen by this one post I found here:

https://developercommunity.visualstudio.com/content/problem/25618/visual-studio-2017-template-issues.html

The one guy provides a possible workaround to 'make it behave like VS2015', but I'm not sure how to utilize his example or what the implications are. Any chance you may have an idea of what's going on there?

@elfprince13

This comment has been minimized.

Show comment
Hide comment
@elfprince13

elfprince13 Apr 3, 2017

Contributor

I avoid VC++ like the plague, for reasons that are neatly summarized by that post. It's a dumpster fire, and I'm shocked that more Windows developers don't jump ship for Clang (Stockholm Syndrome probably has something to do with it...).

Contributor

elfprince13 commented Apr 3, 2017

I avoid VC++ like the plague, for reasons that are neatly summarized by that post. It's a dumpster fire, and I'm shocked that more Windows developers don't jump ship for Clang (Stockholm Syndrome probably has something to do with it...).

@Areloch

This comment has been minimized.

Show comment
Hide comment
@Areloch

Areloch Apr 4, 2017

Contributor

Hahaha, fair enough!

Luckily, they've actually started pushing towards clang themselves. 2017 includes the experimental clang compiler option, and their shader compiler stuff is starting to target clang as well.

But yeah, fair enough. If it's too janky to worry about, we'll just PSA to use 2015 or wait on the patch for 2017(or use clang ;) )

Contributor

Areloch commented Apr 4, 2017

Hahaha, fair enough!

Luckily, they've actually started pushing towards clang themselves. 2017 includes the experimental clang compiler option, and their shader compiler stuff is starting to target clang as well.

But yeah, fair enough. If it's too janky to worry about, we'll just PSA to use 2015 or wait on the patch for 2017(or use clang ;) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment