
Constant Time - ingve
https://dave.cheney.net/2019/06/10/constant-time
======
stouset
The piece starts off with

> “Numbers are just numbers, you’ll never see 0x80ULL in a .go source file”.

Yet almost immediately afterward, we see the expression:

    
    
        const uintSize = 32 << (^uint(0) >> 32 & 1)
    

How is `uint(0)` not just `0u` by another name? And doesn't this code snippet
unnecessarily depend on specifically 32-bit and 64-bit architectures? As
opposed to something like Rust's `mem::size_of::<T>()` which is both constant-
time and also will "just work" on any conceivable architecture past and
present?

~~~
apta
It's just more golang hype that people read without questioning. int and uint
are just one of the many golang mistakes (ironically, another one is mentioned
in the article: the way time is defined).

Finally, just repeating that "golang consts are powerful" doesn't make them
so.

------
nemo1618
>We can’t use unsafe.SizeOf as it is not a constant expression

I'm not sure why Dave claims this, since the docstring of unsafe.Sizeof says,
"The return value of Sizeof is a Go constant," and this can be trivially
verified:
[https://play.golang.org/p/OvShLD4KLKY](https://play.golang.org/p/OvShLD4KLKY)

By the way, it turns out you can exploit Go's map initialization rules to
assert arbitrary boolean expressions at compile time:
[https://twitter.com/lukechampine/status/1026695476811390976](https://twitter.com/lukechampine/status/1026695476811390976)

And this turns out to be rather useful in combination with unsafe.Sizeof,
since you can use it to write compile-time assertions about the size of your
types.

------
throwaway34241
> you’ll see how constant expressions are used to set up complex invariants
> based on the word size of the machine the code is compiled on.

It's a minor detail but this definitely should be "compiled for" instead of
"compiled on", cross-compilation would not work correctly otherwise.

Aside from that I'm not sure if using extra types and constants to prevent
stderr etc from being modified is an improvement. Sure you could maybe cause a
race condition by changing it in the middle of writing, but how often are new
programmers changing stderr at all? What's probably more common is setting it
once at the beginning of the program, for example to redirect stderr to logcat
on Android. And this change doesn't fix bugs in any legitimate uses, it simply
makes them impossible. So I'm not sure who benefits, people who are modifying
stderr in a buggy way, but had no reason to do so at all and just didn't
realize it?

Same thing with sentinel values. Does any major Go program work by reassigning
io.EOF? Has anyone done it by accident _ever_?

Generally, I don't think the threat model should be a willfully malicious
programmer trying to cause problems, or at least it's not a useful model for
Go since it's already totally inadequate for dealing with that scenario at a
language level.

Rather than what's theoretically possible I think it would be better to focus
on what mistakes are commonly made (or have especially severe consequences
like security vulnerabilities) and only add program/language complexity where
a cost/benefit analysis shows a strong case. That's not to say there isn't one
here but I'm unconvinced by the provided examples or personal Go experience.

------
saagarjha
> It doesn’t matter what names you give them, 1 is always stdout

No: if you close a file descriptor, the kernel should be able to reuse it for
new files that you open.

~~~
eridius
And if fd 1 is reused for something, that something becomes, by definition,
stdout.

------
ohazi

        const uintSize = 32 << (^uint(0) >> 32 & 1)
    

> If we’re on a 64 bit platform then the exclusive or of the number zero–all
> zero bits–is a number with all bits set, sixty four of them to be exact.

That's not exclusive or, that's bitwise complement (~ in C). Go reuses the
carat symbol for this, but xor needs two inputs.

~~~
clappski
Why does Go redefine `^` to mean something that it doesn't mean in all the
programming languages I know? Is there a reason that xor isn't `^`?

------
_bxg1
> Because, by definition, sentinel errors are exported public variables, any
> code that imports, for example, the io package could change the value of
> io.EOF.

I haven't tried Go but this already makes it look... dubious.

~~~
apta
it's another drop in the bucket of things that make dealing with golang code
bases messy and error prone

------
jmbi
I wonder why this hasn't been implemented in the standard library yet. People
have been doing this for at least 3 years, and the benefits Cheney listed are
real.

Another Go constant feature I would love is pure function compile time
initialization. It will never happen, but I can dream.

