Why is there no "<const> declared and not used" compile error?

463 views
Skip to first unread message

Markus Zimmermann

unread,
Sep 12, 2016, 8:57:15 AM9/12/16
to golang-nuts
Hi gophers!

I am wondering why we have a "declared and not used" compile error for variables [https://play.golang.org/p/KLzHVO5L7q] but not for constants [https://play.golang.org/p/JG9dSa_VKg]? I am sure there is some rational decision behind this that I have missed, but my Google-fu is just not strong enough to find an answer.

Cheers,
Markus

Sjon Kosse

unread,
Sep 12, 2016, 9:21:50 AM9/12/16
to golang-nuts
Hello,

Const values can be accesed still by reflection in a reasonable manner. This question has come by quite a few times before on the mailing list, better explanations should be easy to find.

adon...@google.com

unread,
Sep 12, 2016, 9:41:35 AM9/12/16
to golang-nuts
On Monday, 12 September 2016 08:57:15 UTC-4, Markus Zimmermann wrote:
Hi gophers!

I am wondering why we have a "declared and not used" compile error for variables [https://play.golang.org/p/KLzHVO5L7q] but not for constants [https://play.golang.org/p/JG9dSa_VKg]? I am sure there is some rational decision behind this that I have missed, but my Google-fu is just not strong enough to find an answer.

I suspect the answer is: because unused constants and types cost nothing at run time.  It's not that simple, of course, because constant and type declarations may be the only uses of an import of a package whose initialization has some cost; but this is quite marginal.

Markus Zimmermann

unread,
Sep 13, 2016, 8:22:37 AM9/13/16
to golang-nuts, adon...@google.com

The const declaration of my example is inside an unexported function body. It can not be accessed by an import. So, it should really matter only at compile time, right? However, I am referring to the definition of https://golang.org/doc/faq#unused_variables_and_imports which states "... Go refuses to compile programs with unused variables or imports, trading short-term convenience for long-term build speed and program clarity." Which holds true in the same way for an unused const as it does for an unused variable. However, even though it produces the same results, i.e. a new declaration which decreases the program clarity, only the variable declaration is marked. Additionally, if an unused constant is compiled into the binary it does also matter to the binary size, even just a little bit.

Cheers,
Markus

Markus Zimmermann

unread,
Sep 13, 2016, 8:41:49 AM9/13/16
to golang-nuts
On Monday, September 12, 2016 at 3:21:50 PM UTC+2, Sjon Kosse wrote:
Hello,

Const values can be accesed still by reflection in a reasonable manner. This question has come by quite a few times before on the mailing list, better explanations should be easy to find.


I do not think that this is true. Wouldn't this already break the first reflection law? How can you examine something with the reflection package without mentioning it in the source code? Where would the interface value come from? Additionally, my example does not export anything, it is a constant inside an unexported function.


Cheers,
Markus

Alan Donovan

unread,
Sep 13, 2016, 9:50:12 AM9/13/16
to Markus Zimmermann, golang-nuts
On 13 September 2016 at 08:22, Markus Zimmermann <zim...@gmail.com> wrote:
On Monday, September 12, 2016 at 3:41:35 PM UTC+2, adon...@google.com wrote:
unused constants and types cost nothing at run time.  It's not that simple, of course, because constant and type declarations may be the only uses of an import of a package whose initialization has some cost; but this is quite marginal.

The const declaration of my example is inside an unexported function body. It can not be accessed by an import. So, it should really matter only at compile time, right?

Right.  The import case I was referring to is this:

import "p"
func main() {
  const unused = p.K
}

The unused constant causes p to be an (unnecessary) dependency, which in turn causes p.init to be executed.

However, I am referring to the definition of https://golang.org/doc/faq#unused_variables_and_imports which states "... Go refuses to compile programs with unused variables or imports, trading short-term convenience for long-term build speed and program clarity." Which holds true in the same way for an unused const as it does for an unused variable. However, even though it produces the same results, i.e. a new declaration which decreases the program clarity, only the variable declaration is marked.

You are right that the motivation given in the FAQ should apply equally to constants and types.

 Additionally, if an unused constant is compiled into the binary it does also matter to the binary size, even just a little bit.

An unused constant is unlikely to affect the size of the final executable since in a typical compiler generates code or data for a constant only when it is used. It will be present in the intermediate .a files though.

Markus Zimmermann

unread,
Sep 14, 2016, 9:32:18 AM9/14/16
to golang-nuts, zim...@gmail.com, adon...@google.com
On Tuesday, September 13, 2016 at 3:50:12 PM UTC+2, Alan Donovan wrote:
On 13 September 2016 at 08:22, Markus Zimmermann <zim...@gmail.com> wrote:
On Monday, September 12, 2016 at 3:41:35 PM UTC+2, adon...@google.com wrote:
unused constants and types cost nothing at run time.  It's not that simple, of course, because constant and type declarations may be the only uses of an import of a package whose initialization has some cost; but this is quite marginal.

The const declaration of my example is inside an unexported function body. It can not be accessed by an import. So, it should really matter only at compile time, right?

Right.  The import case I was referring to is this:

import "p"
func main() {
  const unused = p.K
}

The unused constant causes p to be an (unnecessary) dependency, which in turn causes p.init to be executed.

This holds true for every declaration with an initialization, and should be therefore be no reason to allow such unused constant declarations. There is also already the official idiom to use the blank identifier as the explicit package name if someone really needs p.init to be executed.

However, I am referring to the definition of https://golang.org/doc/faq#unused_variables_and_imports which states "... Go refuses to compile programs with unused variables or imports, trading short-term convenience for long-term build speed and program clarity." Which holds true in the same way for an unused const as it does for an unused variable. However, even though it produces the same results, i.e. a new declaration which decreases the program clarity, only the variable declaration is marked.

You are right that the motivation given in the FAQ should apply equally to constants and types.

Do you think this might be worth bringing up in golang-dev?

Alan Donovan

unread,
Sep 14, 2016, 9:37:10 AM9/14/16
to Markus Zimmermann, golang-nuts
On 14 September 2016 at 09:32, Markus Zimmermann <zim...@gmail.com> wrote:
Do you think this might be worth bringing up in golang-dev?

No.  We can't make this change to the language without breaking existing programs.

Markus Zimmermann

unread,
Sep 14, 2016, 9:43:14 AM9/14/16
to golang-nuts, zim...@gmail.com, adon...@google.com

That is unfortunately. I will just write a linter check for that. Thanks for the talk!

Chris Hines

unread,
Sep 14, 2016, 9:47:29 AM9/14/16
to golang-nuts
It may be a stretch, but allowing unused constants may be desirable when we're using iota and we don't want higher constants to change when some of the intermediate values become unused.

Markus Zimmermann

unread,
Sep 14, 2016, 9:52:37 AM9/14/16
to golang-nuts

No reason to keep an unused constant for that. You can use the blank identifier https://play.golang.org/p/A55mWz_c93

Ian Lance Taylor

unread,
Sep 14, 2016, 11:55:48 AM9/14/16
to Markus Zimmermann, golang-nuts, Alan Donovan
Personally I feel like an unused variable normally indicates a
problem. You set the variable to something, but you never used it.
Why not? There is simply no reason to have an unused variable.

An unused constant does not normally indicate a problem. Constants
can be documentation. They can mean "this value means this" even if
the value is never actually used. I think it's uncommon for an unused
constant to indicate a programming error.

Fortunately, this is a question that can be determined empirically.
Write the code to detect unused constants. Run it over a diverse code
base, such as a bunch of github repos. See how many actual bugs it
detects. Actual data can help decide whether this is worth doing.

Ian

Volker Dobler

unread,
Sep 14, 2016, 1:52:20 PM9/14/16
to golang-nuts, zim...@gmail.com, adon...@google.com
I think it is perfectly fine to have constants which are unused inside a package:
A package exporting just a bunch of physical constants (think of c, alpha, h, ...)
but not using any of them seems useful and not a sign of an error or even a hint
for current or future problems.

Regarding UNexported constants: I could imagine myself defining some
physical constants from other constants, e.g.
  const RK = 25812.8074555
  const rk = h/(e*e)
with the exported RK the official measured value and rk the value as computed
(from other constants).
Now rk serves as a nice documentation and test can compare RK and rk and
do some sanity checking (for this rk could live in a _test.go file, I know and
would be used.)

V.

 

unread,
Sep 14, 2016, 2:14:29 PM9/14/16
to golang-nuts
A difference:
  • it isn't possible to derive the address of a named variable from the address of another named variable
  • it is possible to derive the value of a named const from another named const
const (
    a = 0   // b-1, c-2
    b = 1   // a+1, c-1
    c = 2   // a+2, b+1
)

Reflection needs to be put aside because it can be made to access almost anything we want.

simon place

unread,
Sep 14, 2016, 2:51:25 PM9/14/16
to golang-nuts
what about when you're writing a lib, can't the importing code make use of constants?

Ian Lance Taylor

unread,
Sep 14, 2016, 4:35:59 PM9/14/16
to simon place, golang-nuts
On Wed, Sep 14, 2016 at 11:51 AM, 'simon place' via golang-nuts
<golan...@googlegroups.com> wrote:
> what about when you're writing a lib, can't the importing code make use of
> constants?

No warning about an unused variable or constant would ever apply to an
exported name. That would not make sense.

Ian

> On Monday, 12 September 2016 13:57:15 UTC+1, Markus Zimmermann wrote:
>>
>> Hi gophers!
>>
>> I am wondering why we have a "declared and not used" compile error for
>> variables [https://play.golang.org/p/KLzHVO5L7q] but not for constants
>> [https://play.golang.org/p/JG9dSa_VKg]? I am sure there is some rational
>> decision behind this that I have missed, but my Google-fu is just not strong
>> enough to find an answer.
>>
>> Cheers,
>> Markus
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages