Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: "²" - stray '\262' in program

45 views
Skip to first unread message

Mr Flibble

unread,
Feb 20, 2016, 7:18:06 PM2/20/16
to
On 20/02/2016 23:31, Stefan Ram wrote:
> #include <iostream>
> constexpr double operator "" ²( long double const d ){ return d*d; }
> int main(){ ::std::cout << 3.00² << '\n'; }
> [Error] stray '\262' in program
>
> Alas, the compiler is right. Still, it would have been nice, if
> the program would just have printed »9«. What's working is:

That character does not feature on most people's keyboards so adding
language support for it wouldn't be particularly useful.

/Flibble

Alf P. Steinbach

unread,
Feb 20, 2016, 7:29:37 PM2/20/16
to
On 21.02.2016 00:31, Stefan Ram wrote:
> #include <iostream>
> constexpr double operator "" ²( long double const d ){ return d*d; }
> int main(){ ::std::cout << 3.00² << '\n'; }
> [Error] stray '\262' in program
>
> Alas, the compiler is right.

No, it isn't.

Standard C++ allows the full set of Unicode "identifier" characters just
as in other languages, but the g++ compiler supports only ASCII.

However, the program should not compile because you need an underscore
between `""` and `²`, otherwise the name is /reserved/.


> Still, it would have been nice, if
> the program would just have printed »9«. What's working is:
>
> #include <iostream>
> constexpr double operator "" _2( long double const d ){ return d*d; }
> int main(){ ::std::cout << 3.00_2 << '\n'; }

Or you can do this:

#include <iostream>

constexpr auto operator""_²( long double const d )
-> long double
{ return d*d; }

auto main() -> int { std::cout << 3.00_² << '\n'; }

Except for the non-conforming behavior of g++, of course. <g/>


> The following also does not work:
>
> #include <iostream>
> #include <cmath>
>
> constexpr double operator ^
> ( double const x, double const y )
> { return ::std::pow(x,y); }
>
> int main(){ ::std::cout << 3.00 ^ 2.00 << '\n'; }
>
> Of course, the compiler is right, but the committee could have
> said: Ok, we reserve »^« for integral types, but the user can
> overload it for floating-point types. (It still would not have
> the right priority and associativity.)

I think the language design here is about the best possible, given the
requirement to support C as a subset.

It makes sense to not be able to redefine the meaning of operators for
built-in types.

But if you're willing to accept some quirks, you can define a
pseudo-operator like `%ᛏ%` (it gets the precedence etc. of `%`):

#include <iostream>
#include <math.h> // ::pow

struct Power_op {};
const Power_op ᛏ; // Runic letter Tîwaz Týr, U+16CF

struct Power_base { double const value; };

auto operator%( double const base, Power_op const )
-> Power_base
{ return {base}; }

auto operator%( Power_base const base, double const exponent )
-> double
{ return ::pow( base.value, exponent ); }

auto main() -> int
{
::std::cout << 3 %ᛏ% 2 << '\n';
}

Of course, as before, the g++ non-conforming character set limitation
means that it won't work with that compiler without preprocessing.

I didn't make those operators `constexpr` because `::pow` isn't.


Cheers & hth.,

- Alf

David Brown

unread,
Feb 21, 2016, 6:15:23 AM2/21/16
to
It features on a great many people's keyboards - on mine, I can write x²
as "x" then altgr+shift+2, or "x" then ^ (dead key) then 2, or "x" then
compose then "s" then "2". I'm sure there must be a way to do it in
Windows too.

On the other hand most of the extended identifier characters allowed in
C++ and C are totally impractical to type directly, yet they /are/
allowed. It seems that the guiding rule for which characters are
allowed is that letters were allowed but not symbols.


David Brown

unread,
Feb 21, 2016, 6:30:12 AM2/21/16
to
On 21/02/16 01:29, Alf P. Steinbach wrote:
> On 21.02.2016 00:31, Stefan Ram wrote:
>> #include <iostream>
>> constexpr double operator "" ²( long double const d ){ return d*d; }
>> int main(){ ::std::cout << 3.00² << '\n'; }
>> [Error] stray '\262' in program
>>
>> Alas, the compiler is right.
>
> No, it isn't.
>
> Standard C++ allows the full set of Unicode "identifier" characters just
> as in other languages, but the g++ compiler supports only ASCII.
>
> However, the program should not compile because you need an underscore
> between `""` and `²`, otherwise the name is /reserved/.

You can happily define something like the operator "" s, even though it
is reserved - the compiler will not and should not refuse to compile it.
(It might give you a warning, which is always helpful.) User usage of
reserved identifiers is a not a language error.

>
>
>> Still, it would have been nice, if
>> the program would just have printed »9«. What's working is:
>>
>> #include <iostream>
>> constexpr double operator "" _2( long double const d ){ return d*d; }
>> int main(){ ::std::cout << 3.00_2 << '\n'; }
>
> Or you can do this:
>
> #include <iostream>
>
> constexpr auto operator""_²( long double const d )
> -> long double
> { return d*d; }
>
> auto main() -> int { std::cout << 3.00_² << '\n'; }
>
> Except for the non-conforming behavior of g++, of course. <g/>
>

It works in clang, which has proper support for extended identifiers
(unlike gcc). If you don't have the underscore, you get a warning,
which is nice.
The unfortunate thing about something like this is that you really have
to stretch the choice of symbol. The rune here is classified as a
letter allowed by the C and C++ standards - but you don't see it on
keyboards, and it is rarely included in fonts, making it highly
impractical in use. On the other hand, the up-arrow ↑ is often easily
typed (at least on some keyboards) and exists in many fonts - but it is
not allowed in identifiers. (I don't know why ² is allowed - it is more
of a symbol than a letter.)


Mr Flibble

unread,
Feb 21, 2016, 8:30:56 AM2/21/16
to
On 21/02/2016 11:14, David Brown wrote:
> On 21/02/16 01:17, Mr Flibble wrote:
>> On 20/02/2016 23:31, Stefan Ram wrote:
>>> #include <iostream>
>>> constexpr double operator "" ²( long double const d ){ return d*d; }
>>> int main(){ ::std::cout << 3.00² << '\n'; }
>>> [Error] stray '\262' in program
>>>
>>> Alas, the compiler is right. Still, it would have been nice, if
>>> the program would just have printed »9«. What's working is:
>>
>> That character does not feature on most people's keyboards so adding
>> language support for it wouldn't be particularly useful.
>>
>
> It features on a great many people's keyboards - on mine, I can write x²
> as "x" then altgr+shift+2, or "x" then ^ (dead key) then 2, or "x" then
> compose then "s" then "2". I'm sure there must be a way to do it in
> Windows too.

I cannot do it on Windows ergo my assertion still stands mate: it would
not be a useful addition to the language.

/Flibble

Öö Tiib

unread,
Feb 21, 2016, 2:05:01 PM2/21/16
to
On vanilla Windows (without using special text editor) that ² can be
entered by pressing left Alt, typing 0178 on numpad (numlock must be on)
and releasing left Alt.

However that does not matter. For most it is too complicated and half of
software will just die down or transform it into some odd garbage anyway.
It is especially funny when some (really prominent and popular) site
asks me to supply a good password and few seconds later that my
password contains illegal symbols. What? The symbols have been like such
for decades. Please, no operator² on planet with such dumb programmers.

Vir Campestris

unread,
Feb 21, 2016, 3:54:32 PM2/21/16
to
On 21/02/2016 00:29, Alf P. Steinbach wrote:
> Or you can do this:
>
> #include <iostream>
>
> constexpr auto operator""_²( long double const d )
> -> long double
> { return d*d; }
>
> auto main() -> int { std::cout << 3.00_² << '\n'; }
>
> Except for the non-conforming behavior of g++, of course. <g/>

Alf, I'm obviously not up to date on the standards here. Last time I
rummaged you could only define operator <something> where <something>
was one of the standard operators, like +. Could you give me a link
where I can read about this stuff please?

I seriously thought my newsreader was trying to do something clever,
like when it turns : ) (without a space) into a smiley.

Andy

Alf P. Steinbach

unread,
Feb 21, 2016, 4:15:23 PM2/21/16
to
On 21.02.2016 21:54, Vir Campestris wrote:
> On 21/02/2016 00:29, Alf P. Steinbach wrote:
>> Or you can do this:
>>
>> #include <iostream>
>>
>> constexpr auto operator""_²( long double const d )
>> -> long double
>> { return d*d; }
>>
>> auto main() -> int { std::cout << 3.00_² << '\n'; }
>>
>> Except for the non-conforming behavior of g++, of course. <g/>
>
> Alf, I'm obviously not up to date on the standards here. Last time I
> rummaged you could only define operator <something> where <something>
> was one of the standard operators, like +. Could you give me a link
> where I can read about this stuff please?

Oh, they're C++11 user defined literals. That is, a way to define a
suffix for a literal, so that the compiler invokes a corresponding
function to produce whatever you want for that suffix. E.g. the standard
provides suffix `s` to generate a `std::string`, like the literal
`"blah"s` (the compiler passes "blah" to a conversion func).

General discussion in the FAQ:
<url: https://isocpp.org/wiki/faq/cpp11-language#udls>

Technical info, nearly as good as the standard:
<url: http://en.cppreference.com/w/cpp/language/user_literal>.


> I seriously thought my newsreader was trying to do something clever,
> like when it turns : ) (without a space) into a smiley.

:)

David Brown

unread,
Feb 22, 2016, 3:43:35 AM2/22/16
to
You can always try something like <https://github.com/SamHocevar/wincompose>

I am not suggesting that making this ² operator is a good idea - it's
not easily readable, and too few compilers support extended identifiers
properly (I don't know of any other than clang).

All I am saying is that a lot of people /can/ type such characters
fairly easily, and those that can't (because they are limited by
Windows) can add third-party software to get such features.

In most cases, of course, the benefit of extended identifiers is for
non-English language programmers to be able to use identifiers in their
own language - typing with their normal keyboard layout.




Mr Flibble

unread,
Feb 22, 2016, 2:43:07 PM2/22/16
to
On 22/02/2016 08:43, David Brown wrote:

> In most cases, of course, the benefit of extended identifiers is for
> non-English language programmers to be able to use identifiers in their
> own language - typing with their normal keyboard layout.

Feel free to name one country that doesn't use Arabic numerals or the
asterisk or equals sign. To square a number:

r = n * n;

/Flibble

Paavo Helde

unread,
Feb 22, 2016, 4:24:47 PM2/22/16
to
On 22.02.2016 21:43, Mr Flibble wrote:
>
> Feel free to name one country that doesn't use Arabic numerals

Why, that's Arabia of course :)

Eastern Arabic ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩

Perso-Arabic variant ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹

Urdu variant ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹


Vir Campestris

unread,
Feb 23, 2016, 4:42:30 PM2/23/16
to
On 21/02/2016 21:15, Alf P. Steinbach wrote:
>
> Oh, they're C++11 user defined literals.

<snip>
>
> Cheers & hth.,
>
It helps a lot. Thanks! Shame I'm writing a lot of C these days...

Andy

0 new messages