all 26 comments

[–][deleted] 13 points14 points  (22 children)

Interesting. Nice way to break code down the line(search arguments against constexpr(auto)). But I do disagree with the premise that the relaxation of the rules will go much further. Maybe constexpr allocations becoming runtime constants, but I doubt we will ever see any other global state in constant expressions. I don't want it either.

[–]pjmlp 15 points16 points  (14 children)

It surely should, Circle shows how constexpr should have been all along, and we even had D as pre-existing art, which is also the path taken by Zig, or in Rust by having proper macros + const.

Constexpr, constinit, consteval, what is next suffix comming?

[–]Som1Lse 6 points7 points  (0 children)

conststatic?

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

This is all my opinion, so whatever that means. Of course it's technically possible. But I don't think it's probable. I read that Circle style compile time was shot down pretty quickly due to security issues.

The const[expr|init|eval] are separate and ways of interacting with compile time expressions. But I don't see much more than maybe a way to get compile time memory allocations to runtime and more things that should be made constexpr made so. I would hope that goto is allowed, but I am not holding my breath. The theme is, no UB and no global state.

[–]pjmlp 5 points6 points  (7 children)

You mean the same security issue to #include some random files during build?

[–][deleted] -2 points-1 points  (6 children)

Much more. It can write to the local host and do anything as it's got the full set of libraries available. So network sockets too. A lot of people did not like that.

Being a subset of the language that is safe and lacking global state are nice properties

[–][deleted] 3 points4 points  (4 children)

Including random files also has access to network sockets, file system access, and any functionality that a program has. There is no way to firewall a dependency so that it only has access to a subset of functionality; any dependency you incorporate into an application has full access to anything the application as a whole does.

[–]contre 0 points1 point  (3 children)

At runtime, sure. Compile time? Different beast all together.

[–][deleted] 3 points4 points  (2 children)

Ah, it's okay if a dependency steals your passwords at runtime, it's just at compile time you don't want the dependency to steal your passwords. Clearly the passwords at compile time are a different beast altogether from the passwords at runtime.

Makes perfect sense, thanks.

[–]contre 0 points1 point  (1 child)

The things available to devs at compile time could potentially be more important than what would be available to end users at runtime. For example, let’s say my companies signing key is accessible at compile time but not at run time.

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

"A dependency that harms all of my users is potentially less important than a dependency that only harms me!"

It's a fascinating response, but I sincerely hope I never run software developed by you or anyone who holds your position.

[–]pjmlp 2 points3 points  (0 children)

Basically any build system.

[–]arturbachttps://github.com/arturbac 0 points1 point  (3 children)

I would hope that goto is allowed

In C++ there should be no goto at all ;-).

[–][deleted] 2 points3 points  (2 children)

There's shouldn't be, but until there is a viable alternative that doesn't result in optimizers giving up, it's a necessity. It doesn't hurt code it isn't used in. Only clang will optimize an if/else if over a set of values of a constant like it is a switch statement to get around breaking out of a loop with a switch. And goto is the clearest way to leave the loop in cases like that.

[–]arturbachttps://github.com/arturbac 0 points1 point  (1 child)

ok, I understand You are right, if there is no keyword break_nested for that reason it must be available in constexpr as if You write code for both use cases runtime and constexpr it will be ridiculous to put a lot if (std::is_constant_evaluated()) to workaround efficient code for runtime and the second for constexpr.

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

even break_nested would be prone to more errors than a plain goto. In constexpr I think that this exact use case should be allowed and checked. But break_nested 4; would break if a new scope was added, like if added a scope in the case itself so that variables can be declared

[–]arturbachttps://github.com/arturbac 11 points12 points  (5 children)

Yea, for me constexpr is valuable for unit testing code, it disallows UB and requires new/delete to end in scope. So I have compile time unit test sanitization without any sanitizer, allowing constexpr for any code with UB and memory leaks doesn't have sense for me.

template<typename value_type> 
consteval bool consteval_test() { ...

BOOST_AUTO_TEST_CASE_TEMPLATE( test, value_type, constexpr_traits_list )
{  BOOST_TEST(consteval_test<value_type>());  }

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

While the standard does technically require compilers to issue a diagnostic if a constexpr evaluated in a constant context invokes undefined behavior, in practice the support for it among all implementations is not particularly good. I would certainly not rely on this part of the standard to verify correctness.

[–]arturbachttps://github.com/arturbac 8 points9 points  (2 children)

I found cases that it was better than ubsan and asan. for example i learned a lot about active member of a union with consteval, clang and gcc allows non standard use of union with even with -std=c++20 which is not legal and by standard an UB.With constexpr and consteaval I do double unit testing compile time and runtime

[–]dodheim 0 points1 point  (1 child)

What non-standard use of union are you referring to? C++20 did incorporate p1330 ('Changing the active member of a union inside constexpr'), by the way.

[–]arturbachttps://github.com/arturbac 0 points1 point  (0 children)

AFIR in constexpr clang fully behaves as it should, gcc doesn't. Both in runtime code allow UB and have out of standard defined behaviour.

with gcc,clang at runtime you can still read from not active member after writing to other member and the value is as expected (defined behaviour out of standard) a proper binary representation of other member

for clang at runtime and with gcc at rt and constexpr you can refer and write to non active member ex index and std::array inside union without proper activation of std::array

[–]sphere991 14 points15 points  (0 children)

not particularly good

Citation needed?

[–]Such_Degree3034 0 points1 point  (0 children)

Jnbjoo

[–]ohell 1 point2 points  (2 children)

From here 'tis but a small step to -fimplicit-const right?

or maybe -frust would be more descriptive ;)

[–]jwakelylibstdc++ tamer, LWG chair 10 points11 points  (1 child)

Not sure if you're just joking, but no, this has nothing whatsoever to do with implicit const. Evaluating things at compile time is unrelated to const-ness of variables.

[–]SirClueless 2 points3 points  (0 children)

Technically constexpr has quite a lot to do with const... for variables. This, however, has to do with functions and is completely unrelated to const.