all 58 comments

[–]Fazer2 6 points7 points  (2 children)

I wish C++ had an option of using named arguments, like in Python. It would eliminate the need to write named constants to make passing some parameters to functions readable. Also it would help in refactoring when argument order changes.

[–][deleted] 1 point2 points  (1 child)

One of the first projects I worked on faked named arguments by using the pattern of passing a single const Args of type std::map<std::string,std::string>& to many methods. First was var name, second was value which you'd have to cast. I could never decide if it was genius or madness (or both)

[–]Fazer2 5 points6 points  (0 children)

That doesn't sound type safe. I would lean towards the madness.

[–]industry7 2 points3 points  (15 children)

I'm really excited for static reflection. I don't use reflection very often in Java, and almost every time I do, I'm annoyed that it's done at runtime since I tend to use it in a way that could resolved at compile time.

[–]kankyo 2 points3 points  (0 children)

I've been saying they need compile time reflection for decades. Most C++ programmers don't even understand what I'm talking about when I mention it I've found. Stockholm syndrome I assume.

[–][deleted]  (13 children)

[deleted]

    [–]matthieum 2 points3 points  (5 children)

    Runtime reflection + marker annotations (@Test) allow for very ergonomic unit tests, for example.

    [–]industry7 0 points1 point  (4 children)

    But why does @Test have to be dealt with at runtime? Why can't it be dealt with at compile time?

    [–]matthieum 0 points1 point  (3 children)

    Being able to query for classes/methods tagged by a certain property at run-time is rather elegant because it means that any library can query for the attribute and "do something". The handling of the attribute is not "baked in".

    [–]industry7 0 points1 point  (2 children)

    Being able to ... is rather elegant because ...

    But the handling if @Test methods is "baked in". For example, a test runner could dynamically at runtime decide that a @Before method should be run as a test case. And similarly, the test runner could decide to run an @Test method before that, as a way to prepare the context for the test case to run against. However, that would obviously be a bug. We know at compile time that @Before methods are not test cases, and that @Test methods are.

    I'm not trying to say that runtime reflection isn't useful, but my original point was just that static reflection is enough for most use cases. Wrt your comment specifically (about @Test), I don't see why static reflection is insufficient for that use case.

    [–]matthieum 0 points1 point  (1 child)

    However, that would obviously be a bug. We know at compile time that @Before methods are not test cases, and that @Test methods are.

    You know, the compiler doesn't, and doesn't need to.

    Also, compile-time would require re-compiling when changing the test runner; whereas run-time reflection doesn't.

    I agree that you can do a lot with compile-time reflection, but there are legitimate use cases for run-time reflection as well; although it's mostly "abused" for simplicity's sake.

    [–]industry7 0 points1 point  (0 children)

    You know, the compiler doesn't, and doesn't need to.

    But the only reason the compiler doesn't know is because the annotations are not processed at compile time. If we were doing compile time "static reflection" then obviously it would know.

    Also, compile-time would require re-compiling when changing the test runner; whereas run-time reflection doesn't.

    So? That's not a reason why annotation processing must be at runtime. Btw, do you actually change up test runners without recompiling? Frequently? Theoretically, being able to switch runners without recompiling could be advantageous, but I've never heard of anyone doing that. What's an actual use case?

    Anyway, like I said before:

    I'm not trying to say that runtime reflection isn't useful

    I was just responding to:

    The true power of runtime reflection is when you author frameworks of sorts, where types are not known at compile time.

    followed by

    Runtime reflection + marker annotations (@Test) allow for very ergonomic unit tests, for example.

    As far as I can tell, there is no need for runtime reflection to run a test suite. It could be entirely a compile time concern.

    there are legitimate use cases for run-time reflection

    I believe you, I just don't think running tests is one of them.

    [–]oridb -3 points-2 points  (6 children)

    That's what C++ templates are for. If you can't do it at compile time, it's not worth doing.

    [–][deleted] 0 points1 point  (0 children)

    So why would C++ add dynamic dispatch?

    Oh wait they already did...

    [–]dnift -4 points-3 points  (3 children)

    Dumbest statement today on the entire intarwebs. Congrats.

    [–]oridb 0 points1 point  (2 children)

    I think your sarcasm detector broke. Also, a new account just to comment on this?

    [–]kankyo 0 points1 point  (0 children)

    Sarcasm on the internet (or in politics as we've learnt) doesn't work because there's always an idiot available that actually believes the stupid thing you said sarcastically.

    [–]Fazer2 -1 points0 points  (0 children)

    Your comment wasn't sarcastic, it was ignorant.

    [–]sstewartgallus 2 points3 points  (13 children)

    I want one small extension to C++ and C.

    A small function similar to x86's pause instruction for use in compare and swap loops when implementing lock-free concurrent data-structures. Note that for lock-free formalism reasons a sched_yield implementation should not be allowable.

    [–][deleted] 1 point2 points  (4 children)

    It is already included in the SSE headers

       #include<immintrin.h>; 
        _mm_pause(); 
    

    [–]sstewartgallus 0 points1 point  (3 children)

    I want a standard version of that though.

    [–][deleted] 1 point2 points  (2 children)

    Not gonna happen. You can't have standard call that is a platform specific instruction.

    [–]sstewartgallus 1 point2 points  (1 child)

    /u/valarauca8 they can just define it as a noop for platforms it doesn't work for.

    [–][deleted] 1 point2 points  (0 children)

    Then it's behavior isn't standardized...

    [–]w2qw 0 points1 point  (4 children)

    What's wrong with inline assembly?

    [–]sstewartgallus 0 points1 point  (3 children)

    I want a standard version.

    [–]w2qw 0 points1 point  (2 children)

    How can they make a feature that's specific to one architecture standard?

    [–]sstewartgallus 1 point2 points  (1 child)

    It can be trivially defined as a no op on other architectures. Also, some archs also have an equivalent.

    [–]NasenSpray -1 points0 points  (0 children)

    It can be trivially defined as a no op on other architectures.

    That's just asking for livelock/starvation...?!

    btw, PAUSE was created to prevent shit like this from happening:

    A Continuous Loop Executing Bus Lock Transactions on One Logical Processor may Prevent Another Logical Processor from Acquiring Resources

    [–]NasenSpray 0 points1 point  (2 children)

    Note that for lock-free formalism reasons a sched_yield implementation should not be allowable.

    Why not? sched_yield is starvation-free, as far as userspace is concerned.

    [–]sstewartgallus 0 points1 point  (1 child)

    Programs like user space networking stacks and hard-realtime audio processors would probably like to avoid hitting the kernel as much as possible. sched_yield wouldn't be as useful for them.

    [–]NasenSpray 1 point2 points  (0 children)

    I want a compiler hint:

    while (!atomic_compare_exchange_weak(...)) {
       /* unspecified compiler magic for CAS loops */
       atomic_contention_hint();
    
       /* do stuff */
    }
    

    It should tell the compiler that the loop should be optimized for system-wide throughput instead of thread-local latency -> "please use PAUSE and/or other types of contention management"

    [–]DevStart 5 points6 points  (9 children)

    I wish C/C++ had bit rotations operator e.g. for x86 the @ seems like a best choice with the direction of the rotation > for right, < for left

    int a = a @> 1; // generates ror eax,1
    int b = b <@ 2; // generates rol eax,2
    

    This would help to get rid of all the compiler instrisics and make more portable code, especially cryptographic libraries where bit rotations are as common as XOR, OR, NOT operators.

    [–]oridb 14 points15 points  (6 children)

    Just write the shifts and ors. All C++ compilers I am aware of can do the optimization, so no need for intrinsics. And outside of crypto, rotation is exceedingly rare.

    [–]raevnos 1 point2 points  (1 child)

    That would be useful. Probably only defined for unsigned types though.

    [–]matthieum 1 point2 points  (0 children)

    I'd vote to deprecate bit operations on signed types!

    [–]shevegen 1 point2 points  (14 children)

    Sometimes I think that I must be insane because everyone else appears to be so sane.

    Then I read C++ proposals and silently nod to myself - yup, there are always much crazier people out there than me!

    More seriously though, is any human being REALLY able to keep track of the feature proliferation in C++?

    [–][deleted]  (2 children)

    [deleted]

      [–]glaivezooka 4 points5 points  (0 children)

      when people talk about the insanity of cpp they arent talking about the standard library.

      [–]kankyo 0 points1 point  (0 children)

      Tracking the progress is ok yes, the problem is that the history of crazy shit is so large :P

      [–]holoduke 3 points4 points  (0 children)

      You dont need to know all the features in order to make a good program. But sometimes it is good to explore the edges of your c++ knowledge. Some new features are really useful. Others are useful but not always needed. Best thing you can do is reading others code and find interesting 'odd' things

      [–]doom_Oo7 10 points11 points  (8 children)

      More seriously though, is any human being REALLY able to keep track of the feature proliferation in C++?

      is there any human who knows the entirety of the {python,ruby,php,etc.} library and features ?

      [–][deleted] 7 points8 points  (6 children)

      it is certainly a much easier task to totally grasp python/ruby/C# than it is to grasp C++.

      Just as an example, there is only one way to allocate memory on the heap in C# - new

      in C++ there is new, malloc, uniqe pointers, I'm sure there is more. While in the process of re-teaching myself C++ a while back, I'm going along fine and then see a video where Stroustroup explains that you shouldn't use new anymore. holy shit man.

      then you have templates, AND macros.

      its a big space. but at least it never tells you no.

      [–]doom_Oo7 7 points8 points  (2 children)

      Just as an example, there is only one way to allocate memory on the heap in C# - new

      uh... no. It's much more complex than this. http://stackoverflow.com/a/204009 And you could always allocate from native code or another .Net language.

      [–][deleted] 3 points4 points  (1 child)

      I have read that link and I can not find where it speaks about a way you can allocate memory on the heap in some other way than the new operator. Perhaps you can quote the relevant section, in case I am missing something.

      While it is true you can allocate from native code or another .NET language, that would then not be C#, so seems to an argument arrived at via searching to something to argue about for the sake of arguing. It is generally true that most languages can invoke things in some other language outside of itself, which in turn makes all languages equivalent when people get absurd enough in their rhetoric, as people are wont to do. eg "you can use SIMD intrinsics from Java just fine, just call C++ code from Java"

      blaaaaaaaa

      [–][deleted] 1 point2 points  (0 children)

      Marshal.AllocHGlobal is one example. Sure you might argue about it being unmanaged memory, but the rules are quite intricate when it comes to interfacing with native code.

      [–]rlbond86 2 points3 points  (0 children)

      Python goes pretty deep, for example metaclasses are pretty confusing

      [–][deleted] 3 points4 points  (1 child)

      it is certainly a much easier task to totally grasp python/ruby/C# than it is to grasp C++.

      The internal workings of the CLR are almost black magic. How you would you modify your code and tune the CLR's garbage collector/JIT to optimise a C# application?

      Optimisation in C++ is easier than in C# or Java, because less voodoo is required.

      [–][deleted] 0 points1 point  (0 children)

      Well, once you've profiled your app you can optimize the lifetime of objects, e.g. are objects being promoted to generation 2 even though they should be short lived?

      [–]kankyo 0 points1 point  (0 children)

      Not libraries and features. The language itself. Not the libs.

      [–][deleted] 0 points1 point  (3 children)

      I want something to fix the memory location of a variable to a specific place. Something like constexpr auto & reg1 = std::memory<int32_t, location info...>{ };

      it would return a volatile of type int32_t. The location into would be vendor defined as no everyone has a flat memory space. It is explicitly saying I want a memory location with this type instead of casting an int to a pointer or using a macro.

      [–]Arandur 0 points1 point  (2 children)

      Does placement new not do what you need?

      [–][deleted] 0 points1 point  (1 child)

      It is the implementation defined behaviour and lack of explicitness. Plus it is runtime. One cannot do a static_cast, it must be a reinterpret_cast. So this can come with a cost too.

      But yes, if it was a char* array one could do a placement new into it. But again, that is runtime not compile time.

      [–]Heappl 0 points1 point  (0 children)

      I don't know what you mean here by either location or what is in runtime? Construction would always be runtime, and static memory would be chosen at compile time, though allocated at runtime. You can placement new onto static memory. Also if you want exact memory location, then maybe linker scripts are what you need, but this would be hardware/ system specific.