Hi Martin,

I think this is just one of those cases where C and C++ have different priorities and unfortunately it is impossible to make everyone happy.

In C++, context-sensitive keywords are common, and in this particular case, using context-sensitive keywords for `pre` and `post` allow us to use any identifier we want without breaking any existing code. The keywords `pre` and `post` have been chosen carefully and gained strong consensus (see P1344R1). Replacing them with longer, "uglier" keywords in C++ so that C can have a non-context-sensitive keyword that doesn't start with an underscore is a tradeoff that simply doesn't make sense for C++ and it doesn't have any realistic chance of gaining consensus in SG21 from my perspective.

I do care about C compatibility (which is why I started that thread), but I think that using _Pre and _Post in C is a reasonable compromise, at least for now. This gives you the ability to #define pre _Pre for newer compilers and thus have code with Contracts shared between C and C++, while at the same time macro away Contracts entirely for backwards-compatibility with older compilers. Yes, the macroing away might no longer be possible with post-C++26 extensions, but even then, both code sharing between C and C++ and backwards-compatibility with older compilers can be achieved by wrapping the Contract annotations themselves into macros, like we do for many other features already. This isn't ideal but seems like a reasonable compromise to me. And you are of course free to propose a syntax for the post-C++ extensions that is more compatible with function-like macros than the solutions proposed so far – if such a paper materialises, we will consider it in SG21.

To me, this compromise sounds doable, consistent with what we've done before for other features shared between C and C++, and still better than using [[ ... ]] which apparently in C has the notion of "this is token-ignorable". At least for newer compilers that know about Contracts, token-ignoring Contracts is not something that I would want to allow or encourage. Attributes in C are all either for enabling/disabling warnings or for giving optimisation hints to the backend. Contracts are not like that at all. They are a core language feature and there is nothing "optional" about them – in the sense that an implementation shouldn't be allowed to just not implement them and still be conforming.

Anyway, I hope this makes sense, but if I'm missing something please let me know!

Cheers,
Timur

On 8 Oct 2023, at 09:17, Martin Uecker <ma.uecker@gmail.com> wrote:

Am Samstag, dem 07.10.2023 um 18:35 +0300 schrieb Timur Doumler via Liaison:
Right. I see.

In this case you are right, P2961 as proposed for C++26 seems fully compatible with function-like-macro-ing it away in C if you so desire. The planned post-C++26 extensions are not, but we can deal with that later.

I agree, when it is understood that the extensions
are problematic.


So it seems to me now that — possible post-C++26 extensions aside — the P2961 syntax is actually *more* backwards compatible than the P2935 (attribute-like) syntax. With P2961, you can adopt the same syntax in C using _Pre and _Post as the keywords and then do something along the lines of

#if MY_COMPILER_SUPPORTS_CONTRACTS
 #define pre _Pre
#else
 #define pre(...)  // nothing
#endif

And then you can use standard Contract syntax even with an old compiler! On the other hand, with P2935 (attribute-like syntax), you can't do that, you'd have to wait for your compiler to know at least to ignore the colon inside [[ ... ]] which it doesn't currently do (all major compilers issue a parse error).

@Martin: considering the above, do you have any more thoughts on this?

There is still the issue that "pre" and "post" will collide
with existing code.

And context sensitive keywords do not currently exist and
are also problematic.   _Pre and _Post would work, but our
general goal is to then transition to lower case keywords
later (as we did already for many in C23), and I am not
sure this works for "pre" and "post".

But these issues have been pointed out by others before.

Martin


Cheers,
Timur

On 7 Oct 2023, at 17:44, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:

On Sat, 7 Oct 2023 at 17:37, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
Wait, not quite:, there is the syntax for return values in postconditions which is not a future extension – that's being proposed now:

int f()
post (ret: ret >= 0);

Is that colon in there compatible with function-like macros? Because that's not valid function call syntax at least.

Of course it is, the argument list of a macro is just a token or
multiple tokens. Thus:

#define post(X)

void f(int x, int y)
post(ret: ret >= 0)
{
  (void)x;
  (void)y;
}

https://wandbox.org/permlink/JavMNfd6kGjF9f13

And, for what it's worth, I can make that

post([[]]}}}][][]]]]]]}}}()();;::;;)

which is a parentheses-balanced token sequence and thus a valid
invocation of that function-like macro,
but otherwise contains stuff that's not fathomably valid in any
hypothetical future version of C++, but the macro
slurps it just fine.

_______________________________________________
Liaison mailing list
Liaison@lists.isocpp.org
Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
Link to this post: http://lists.isocpp.org/liaison/2023/10/1294.php