Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Allow const values to be changed through build flags before compilation #22706

Closed
akamensky opened this issue Nov 14, 2017 · 13 comments

Comments

@akamensky
Copy link

I often find myself in need to define some value that should never ever change during the application runtime (e.g. release version). Idiomatically this supposed to be a const, however if I need to set value to it compile-time in Go1.x I am restricted to using var only, which often makes no sense (as in example with release version)

Currently var value can be assigned at linking stage by passing -ldflags "-X main.varname=varval".

I propose to allow setting constants during compile time in same or similar manner.

From my perspective it looks as this won't be a backward compatibility breaking change, so it would be possible to implement in Go1.x (otherwise, perhaps, this can be moved to Go2)

@gopherbot gopherbot added this to the Proposal milestone Nov 14, 2017
@ianlancetaylor
Copy link
Contributor

It's not a bad idea but I don't see any way to implement it. The problem is that the compiler knows that constants can't change, and it optimizes code on that basis. You are proposing a way that a constant can change after the compiler has already run. I don't see a way to do that.

@dominikh
Copy link
Member

The way I understood the proposal, this wouldn't change the constant after the compiler has run. It would be a new flag to the compiler (not the linker's -X flag) that overwrites a constant's value before compilation.

@ianlancetaylor
Copy link
Contributor

Ah, got it, sorry, similar to C's -D option. I got confused by the reference to the linker's -X option.

@odeke-em odeke-em changed the title proposal: Allow setting const value in same manner as var value proposal: Allow const values to be changed through build flags before compilation Nov 14, 2017
@odeke-em
Copy link
Member

I've tweaked the title a little, please feel free to revert or edit it.

@randall77
Copy link
Contributor

If you have a small set of possible values you could choose from among them with build tags (one file per value with appropriate build tags).

@robpike
Copy link
Contributor

robpike commented Nov 14, 2017

The go generate command is a way to achieve nearly the same end, with no changes to the compiler. The restriction would be that the constant would be defined by the package author, not client, but that's often fine.

@griesemer
Copy link
Contributor

If it's just about one or a few constants, you could just as well echo your constant into a small file f.go belonging to your package p instead of providing a flag to your compilation:

echo "package p; const C = $constvalue" > f.go

This is a third method of achieving the same goal. I don't see any reason for adding an additional mechanism to the compiler.

@robpike
Copy link
Contributor

robpike commented Nov 14, 2017

@griesemer And the way to capture that echo is with go generate...

@akamensky
Copy link
Author

@robpike With all due respect, but go generate is an overkill for this and is very hard to understand so that many people end up misusing it (e.g. checking generated files into repositories etc).

Also the proposed option with echo ... and then go generate is going to create a whole lot of mess for those who release their software using some kind of CI/CD systems.

Like mentioned above GCC argument -D can be used together with environment variables, which would allow compiler to [re-]define value on pre-processing time. With some extra flag to compiler this can be done by just passing additional flag where I can specify environment variables (build number, date and just anything I want). Now how am I suppose to get those environment variables in go generate? Shell wrapper that would actually call go ... under the hood and echo values to some files for go generate to see them? I thought Go was striving for simplicity and transparency.

And finally people do actually use -ldflags "-X main.varname=varval" now for exactly this purpose, but everyone confused why can't they do it with constants which would be more semantically appropriate. Just simple search online finds plenty of people confused by the fact that they can set var and not const

@griesemer
Copy link
Contributor

@akamensky I'll have others (@ianlancetaylor?) chime in on the various reasons for linker flags but regarding the constant issue, using echo doesn't require you to use go generate... (even though that would be a nice way to express all that configuration stuff in the code).

In order words, if you are willing to provide a compiler flag you might just as well execute the little echo line and achieve the same thing. That is, there really is an easy existing mechanism that already does what you want using the language as it is.

@akamensky
Copy link
Author

@griesemer yes, I do not disagree. It is possible to do that, my previous comment was about above insisting on using go generate where it does not need to be used. However let's be honest this is far from elegant solution ;) This solution does not make setup of CI/CD much easier as still need to either call that shell script separately or use it as a wrapper for entire build process.

@robpike
Copy link
Contributor

robpike commented Nov 15, 2017

@akamensky I think it is an elegant solution. One of the most important things in system design is knowing where to solve a problem. You can't solve every build problem with compile-time flags. Any realistic build system for a large program deals with enough complexity already that invoking "echo" somewhere is a minor inconvenience at best.

Or to put it another way, making a continuous build bot easier to set up is not a convincing argument, at least to me, for putting code generation into the compiler's command-line arguments.

@rsc
Copy link
Contributor

rsc commented Nov 20, 2017

The ldflags -X option is undeniably useful but also has been a source of confusion. I can only imagine the confusion that would result from changing constants. What happens when you do

go build -gcflags=-Dmath.Pi=5

?

If you want to control debug settings, then build tags work too, as @randall77 noted already. That's certainly better.

We should almost certainly draw the line just after -X for vars.

@rsc rsc closed this as completed Nov 20, 2017
@golang golang locked and limited conversation to collaborators Nov 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants