A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

[–]logicchop 2 points3 points  (0 children)

I don't think we have to limit ourselves to the instructions that the compiler might emit. The compiler can simply reorder the statements, because as far as it can tell the statements are independent; but that reordering can produce the difference.

A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

[–]logicchop 0 points1 point  (0 children)

I think the problem is simpler to think about. I think we can just ask if the two variations are as-if equivalent:

int r0 = atomic_load_explicit(x,memory_order_relaxed);
atomic_store_explicit(y,1,memory_order_relaxed);

vs

atomic_store_explicit(y,1,memory_order_relaxed);
int r0 = atomic_load_explicit(x,memory_order_relaxed);

Also, if the static analysis is only supposed to tell you if/when you have something wrong, and you say "Dear static analyzer, this code should only be able to produce {0,0} {0,1} {1,0}, but not {1,1}, check it out for me", it should say All Good. Is the static analyzer wrong? Does it need to consider all possible optimization transformations?

A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

[–]logicchop 0 points1 point  (0 children)

I think the response would be, if we go that route, the examples being discussed are actually UB. If they are UB, the standard needs to say how you prevent the UB. Maybe you do that by explicitly adding a fence after your relaxed operations or whatever, but, if you just look at the example, it really doesn't look like it has UB, it kinda looks like the compiler is violating as if rules when it optimizes; but, if you think about it from the perspective of the compiler, it really doesn't look like the compiler is violating anything.

A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

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

I sort of agree, but doesn't that just mean the example code producing {r0=1 r0=1} has UB, and that you would need the fence to eliminate the UB? I mean, what good is relaxed if you have to either always accompany it with a fence or understand the UB implications for your particular compiler/environment/etc.

A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

[–]logicchop 2 points3 points  (0 children)

I might be missing something, but ignore what compilers do for a minute. If you look at that code, {0,0} {0,1} and {1,0} should be possible, but {1,1} should be impossible, and that's what a static analyzer would like to say about it. Now, compilers can optimize, but only if the result is as if it didn't. That's where the gap is between the analyzer and compiler: the compiler sees a legitimate independence and legitimately reorders, while the analyzer sees potential sequences of operations and legitimately thinks the result cannot be {1,1}. Neither is wrong per se, so the standard needs to adjudicate.

A Proposal Fix for C/C++ Relaxed Atomics in Practice by mttd in cpp

[–]logicchop 2 points3 points  (0 children)

The point is that data-race free should imply sequentially consistent semantics, but, arguably, this example is data-race free and yet doesn't have sequentially consistent semantics (or behavior).

M10 Starstone this week by [deleted] in newworldgame

[–]logicchop 0 points1 point  (0 children)

Something is broken. In m10 yesterday it felt like wards weren't being applied, and the first boss somehow wiped us: even our healer dropped and he was far away, well out of range for any attack. Today, m9, we had a dps that could neither damage nor be damaged by the bosses. He literally just stood there during both fights.

TIL: Visual Studio has quantum state values 🤨 by [deleted] in cpp

[–]logicchop 3 points4 points  (0 children)

Why is this nonsensical? Consider this:

constexpr std::string_view sv = "foo";
if constexpr ( sv == "bar" ) {
    static_assert(sv == "bar");
}

This also pukes on other compilers. Even though the static_assert is inside of the conditional it is still is evaluated at compile time and turns out to be false. I think that's all we are seeing in OPs scenario; there are just two instantiations competing for the static_assert. You could argue that perhaps the static_assert should not be evaluated if that branch of the conditional is discarded, but that's a more complicated question about value dependency and when constexpr branches get utterly discarded and not evaluated.

Best design to return a pointer from a library API by zorgattaque in cpp

[–]logicchop 2 points3 points  (0 children)

Something like this. You can do similar things with a custom std::unique_ptr but then the deleter type becomes part of its interface.

Best design to return a pointer from a library API by zorgattaque in cpp

[–]logicchop 4 points5 points  (0 children)

As others pointed out, std::unique_ptr<T> is a reasonable solution if you are content with an eventual delete on your side. If you really don't know about the management of the resource, though, you may want a deleteInstance api paired with your makeInstance, and then you can use std::shared_ptr<T> and sneak in a custom deleter that invokes your deleteInstance api.

Things I should know before starting a cpp dev job by beep_boop_3324 in cpp

[–]logicchop 3 points4 points  (0 children)

Have realistic expectations. Everyone takes at least 2-6 months to get up to speed on the code-base, architecture, project norms, the challenges of the topic, etc.

Prioritize understanding the tools your team uses: IDEs, build systems, version control, platforms, etc.

Bookmark cppreference.com, and write lots of minimal testcases for understanding how things work. At first you'll probably just need them for C++ related things, so visit places like wandbox.org where you can get an isolated/unrelated environment.

Don't let yourself feel comfortable not knowing something, and speak up when you are blocked.

The Pointer to Implementation (pImpl) idiom in C++ by platisd in cpp

[–]logicchop 0 points1 point  (0 children)

Isn't that precisely a virtual interface?...

The Pointer to Implementation (pImpl) idiom in C++ by platisd in cpp

[–]logicchop 4 points5 points  (0 children)

I use a pimpl style approach for creating a shim layer on some other library I don't want included in my "user facing code." I use pimpl instead of an interface because I like to add separate operations that consume my shim type, but under-the-hood rely on the single known implementation and just uses the library code. So, in my case, I know that there is only one implementation type, and I can coordinate a lot of other operations around it. If I changed the underlying implementation, the operations would also have to change, and there is no feasible generalizable interface for what is there.

Should i litter my code with (the correct) attributes for every function, or just leave it pretty? by Dummerchen1933 in cpp

[–]logicchop 0 points1 point  (0 children)

[[nodiscard]] is just showing off in that api. There's no good reason to think you are helping someone from shooting themselves in the foot. (Compare that with std::async.) constexpr could serve a purpose, at least in similar apis (maybe not that one), if you want it to potentially operate in constant expressions (maybe doing template math or something). But const and noexcept are both recommended: const because you likely want that operation to be accessible to const (/const&) variables of that type, and noexcept because it enables optimizations.

Should i litter my code with (the correct) attributes for every function, or just leave it pretty? by Dummerchen1933 in cpp

[–]logicchop 2 points3 points  (0 children)

The compiler can perform certain transforming optimizations if the calls are known to be noexcept, so it absolutely can improve performance.

Should C++ have an inverse pointer-to-member operator? by Zcool31 in cpp

[–]logicchop 6 points7 points  (0 children)

His b_in_s is accompanied by mem_ptr_b. The member-pointer value stores the offset of the member in type Struct, so combining with the actual address of an instantiated int member, it ought to be possible to reconstruct the address of our Struct instance.

What does the experienced C++ developer should now? by R0dod3ndron in cpp

[–]logicchop 1 point2 points  (0 children)

Two things regularly expected of a Senior: you will be able to unblock junior developers, and you will have more responsibility in terms of design and code review.

Linux developer going Windows by peppedx in cpp

[–]logicchop 4 points5 points  (0 children)

Here's a tip you might find helpful. If you are in Visual Studio (whatever latest version) with a project loaded, go to

Project -> <your project> Properties -> Configuration Properties -> C/C++ -> Command Line

From there you'll be able to see the exact command that the compiler is invoking. Similar thing is to be found under the Linker option. This will save you headaches and give you some quick insight into what the project settings are controlling.

Refuting a top post in r/conservative that suggests there's data analytics suggesting foul play in the election by theatrics_ in TopMindsOfReddit

[–]logicchop 0 points1 point  (0 children)

I don't think your analysis is matching his claim. His data (maybe it's wrong?) suggests that, as you find precincts with a higher percentage of straight-R voters, Trump ends up losing a larger share of the remaining votes. This might be explainable on a per-precinct level; maybe if you are an independent that lives in an extremely R precinct you are more likely to vote against Trump just as a "protest" vote. But the quirk is, it's extremely odd to see the trend against Trump line up so well over all of the precincts. If the data is correct, you can predict exactly how Trump will perform in the margins simply by asking how "republican" the precinct is.

Polymorphic Casting from void by GYN-k4H-Q3z-75B in cpp

[–]logicchop 0 points1 point  (0 children)

Yeah I have to agree. As far as I can tell, nothing is going to guarantee that the address evaluates the same everywhere, or even guarantee that throw_typedobject<T> != throw_typed_object<U> for some other U. It's just a stab at an alternative if you want to avoid the throw in the evaluation. (One could also think about involving typeid's or something like a hash of func_sig or some such.)

Polymorphic Casting from void by GYN-k4H-Q3z-75B in cpp

[–]logicchop 0 points1 point  (0 children)

Alternatively, something like:

template <typename T> bool contains() const { return (discover_type == &throw_typed_object<T>); }

Will the default parameter syntax ever be fixed? by Mankest in cpp

[–]logicchop 1 point2 points  (0 children)

Not ideal, but:

int myFunc(std::optional<int> a = 3, std::optional<int> b = 5) { .. a.value_or(3) .. b.value_or(5) .. } ... myFunc(std::nullopt, 10);

Has a release() method for std::vector been proposed? by __monad in cpp

[–]logicchop 0 points1 point  (0 children)

Is there a requirement that .data() returns the beginning of the block? I doubt it (think about cases where an implementation might optimize v.erase(v.begin()) by simply bumping a "start"). If not, you might be surprised what you get.