# Compile-time constants

**URL:** <https://discourse.julialang.org/t/compile-time-constants/6039>\
**Category:** General Usage\
**Created:** [September 22, 2017, 2:20pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039 "2017-09-22T14:20:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![foobar\_lv](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@foobar\_lv](https://discourse.julialang.org/u/foobar_lv)\
**Post date:** [September 22, 2017, 2:20pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/1 "2017-09-22T14:20:04Z")

</div>

How does one get actual constants in julia? “actual constant” meaning behavior like #define. As far as I understood, “const” means “constant type”, not “constant value”, i.e. you can dereference or modify constants. This forbids llvm from doing constant elimination. Example code:

let  
const FLAGA::UInt64 = 1\<\<32  
const FLAGB::UInt64 = 1\<\<33

```
global foo
global bar
function foo(x::Int)
    return (0== (x & (FLAGA & FLAGB)))
end
function bar(x::Int)
    return (0== (x & ((1<<32) & (1<<33) ) ) )
end    

```

end  
println(“Foo:”)

@code\_native foo(13)  
println(“\n\nBar:”)  
@code\_native bar(13)

gives:

Foo:  
.text  
Filename: In[1]  
Source line: 286  
testq %rdi, %rdi  
js L8  
Source line: 8  
movb $1, %al  
retq  
L8:  
pushq %rbp  
movq %rsp, %rbp  
Source line: 286  
movabsq $jl\_throw, %rax  
movabsq $140358617188296, %rdi # imm = 0x7FA7C984C7C8  
callq \*%rax  
nopw %cs:(%rax,%rax)

Bar:  
.text  
Filename: In[1]  
pushq %rbp  
movq %rsp, %rbp  
Source line: 11  
movb $1, %al  
popq %rbp  
retq  
nopl (%rax,%rax)

Obviously, the behavior of “bar” is desired in most cases. How do I get it? Of course I could use a macro, but this has the disadvantage of extremely different syntax. In other words, changing between a macro-constant and a “const-type” non-constant requires quite some refactoring of the source code.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 22, 2017, 2:33pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/2 "2017-09-22T14:33:04Z")

</div>

> [@foobar\_lv](#):
>
> As far as I understood, “const” means “constant type”, not “constant value”, i

No, constant means constant binding e.g. if the rhs is immutable the value can be inlined:

```julia
julia> const FLAGB = 1<<33
8589934592

julia> const FLAGA = 1<<32
4294967296

julia> function foo(x::Int)
           return (0== (x & (FLAGA & FLAGB)))
       end
foo (generic function with 1 method)

julia> @code_native foo(13)
	.text
Filename: REPL[3]
	pushq	%rbp
	movq	%rsp, %rbp
Source line: 2
	movb	$1, %al
	popq	%rbp
	retq
	nopl	(%rax,%rax)

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 22, 2017, 2:41pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/3 "2017-09-22T14:41:36Z")

</div>

1. Local constant declaration is ignored, they have no effect.
2. It is inlined, the extra code you get are simply due to different type.

```julia
julia> let
           FLAGA = 1<<32
           FLAGB = 1<<33

           global foo
           function foo(x::Int)
               return (0== (x & (FLAGA & FLAGB)))
           end
       end
foo (generic function with 1 method)

julia> @code_native foo(1)
        .text
; Function <invalid> {
; Location: REPL[1]
        pushq %rbp
        movq %rsp, %rbp
;}
; Function foo {
; Location: REPL[1]:7
        movb $1, %al
        popq %rbp
        retq
        nopl (%rax,%rax)
;}

julia> @code_warntype foo(1)
Variables:
  #self# <optimized out>
  x::Int64

Body:
  begin
      return (0 === (Base.and_int)(x::Int64, (Base.and_int)($(QuoteNode(4294967296)), $(QuoteNode(8589934592)))::Int64)::Int64)::Bool
  end::Bool

```

Also note that how much easier it is to see if the constant is inlined if you use the right tool (i.e. `code_warntype`)

---

<div class="post-metadata">

**Author:** ![foobar\_lv](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@foobar\_lv](https://discourse.julialang.org/u/foobar_lv)\
**Post date:** [September 22, 2017, 3:42pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/4 "2017-09-22T15:42:34Z")

</div>

Thanks!

So the problem was that julia does not understand that UInt64 and Int64 have equivalent behavior with respect to bitwise operations?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 22, 2017, 4:31pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/5 "2017-09-22T16:31:47Z")

</div>

> [@foobar\_lv](#):
>
> UInt64 and Int64 have equivalent behavior with respect to bitwise operations?

They don’t.

```julia
julia> -1 & UInt(1)
ERROR: InexactError: check_top_bit(Int64, -1)
Stacktrace:
 [1] throw_inexacterror(::Symbol, ::Type{Int64}, ::Int64) at ./int.jl:34
 [2] check_top_bit at ./int.jl:428 [inlined]
 [3] convert at ./int.jl:487 [inlined]
 [4] _promote at ./promotion.jl:203 [inlined]
 [5] promote at ./promotion.jl:247 [inlined]
 [6] &(::Int64, ::UInt64) at ./promotion.jl:313

julia> -1 & Int(1)
1

```

---

<div class="post-metadata">

**Author:** ![foobar\_lv](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@foobar\_lv](https://discourse.julialang.org/u/foobar_lv)\
**Post date:** [September 22, 2017, 5:21pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/6 "2017-09-22T17:21:36Z")

</div>

This behavior seems unexpected, coming from C, but I now feel stupid for making assumptions without testing and reading the docs.

Thank you again.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [September 22, 2017, 11:09pm UTC](https://discourse.julialang.org/t/compile-time-constants/6039/7 "2017-09-22T23:09:25Z")

</div>

This is actually about to change on master: [https://github.com/JuliaLang/julia/pull/23827](https://github.com/JuliaLang/julia/pull/23827).
