Compile time conditional checks?

1,139 views
Skip to first unread message

Alex Ray

unread,
Jul 18, 2011, 10:09:58 PM7/18/11
to golang-nuts
I'm looking for an ideomatic way of doing in go what i would do (in C):

#if foo <= 1
#error foo must be greater than 1
#endif

to generate a compile-time error, rather than it going all of the way through the compilation then hitting a test and failing.  This is especially useful in large projects, where you could halt compilation midway instead of going all the way through compilation & linking to the test framework.

I'm throwing this out in light of one of the more recent discussions about go and why some language proposals are rejected.  A few were rejected because:
* Throwing compile-time errors is better than runtime errors; put the problem in the developers lap, not the users (if i got that point correctly)
* Scale well to large projects/codebases

I'll admit the possibility that there's an obvious way to do this that I missed.
Thoughts/ponders/quandaries?

~Alex

Evan Shaw

unread,
Jul 18, 2011, 10:30:01 PM7/18/11
to aj...@ncsu.edu, golang-nuts
On Tue, Jul 19, 2011 at 2:09 PM, Alex Ray <alexjr...@gmail.com> wrote:
> I'm looking for an ideomatic way of doing in go what i would do (in C):
> #if foo <= 1
> #error foo must be greater than 1
> #endif

There's a (slightly hackish) way you can accomplish this right now:

const _ = uint(foo - 2)

The compiler will throw an error if foo - 2 is negative. It will also
throw an error if foo is really big.

I'll leave it to someone else to comment on the feasibility/likelihood
of adding some kind of compile-time assertion mechanism to the
language.

- Evan

unread,
Jul 19, 2011, 6:14:27 AM7/19/11
to golang-nuts
I think we have to wait a few years for the Go compilers to get better
(although future is inherently uncertain). A Go compiler, or a code
checking tool, utilizing partial compile-time evaluation should be
capable of converting some run-time checks into compile-time checks.

Alex Ray

unread,
Jul 19, 2011, 8:09:44 PM7/19/11
to golang-nuts

The problem is what runtime checks would it transform? Also this prevents the compile time checks from being in any kind of conditional statement.

Panic() is the obvious choice, so is there a situation where you would want a panic() built in to the main program flow?

func main() {
  for {
    foo()
  }
  panic("i should never get here")
}

Gustavo Niemeyer

unread,
Jul 19, 2011, 8:39:28 PM7/19/11
to aj...@ncsu.edu, golang-nuts
Hi Alex,

> I'm looking for an ideomatic way of doing in go what i would do (in C):
> #if foo <= 1
> #error foo must be greater than 1
> #endif

Would you have a more concrete example of what "foo" would be here?

> to generate a compile-time error, rather than it going all of the way
> through the compilation then hitting a test and failing.  This is especially
> useful in large projects, where you could halt compilation midway instead of

Is this a real issue you're facing? Even for large projects,
compilation is quite fast.

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/plus
http://niemeyer.net/twitter
http://niemeyer.net/blog

-- I never filed a patent.

andrey mirtchovski

unread,
Jul 19, 2011, 8:42:29 PM7/19/11
to aj...@ncsu.edu, golang-nuts
In my opinion, citing historical precedent, you may never see
compile-time conditional checks in Go. Paired with the fact that the
Plan 9 C compilers don't accept #if, and the fact that the new Go
compilers which grew out of them still produce static Go binaries, the
preference of the Go team may be on the side of
compile-once-execute-ad-infinitum. in Plan 9 people are happily
running 20 year old binaries from the second edition today.

cgo may, however, invalidate the above reasoning.

Kyle Lemons

unread,
Jul 20, 2011, 11:42:47 AM7/20/11
to andrey mirtchovski, aj...@ncsu.edu, golang-nuts
Without conditional compilation, it is "impossible" to write a piece of Go code which will be interpreted differently by (the same compiler on) another system, which vastly increases the confidence a developer can have in his application on a target system.  If we added them, then people would ask for command-line #defines and then someone would write ./configure and then where would we be?

~K

ron minnich

unread,
Jul 20, 2011, 11:43:55 AM7/20/11
to Kyle Lemons, andrey mirtchovski, aj...@ncsu.edu, golang-nuts


in need of much more prozac than we are now.

ron

Brad Fitzpatrick

unread,
Jul 20, 2011, 12:21:19 PM7/20/11
to Kyle Lemons, andrey mirtchovski, aj...@ncsu.edu, golang-nuts
On Wed, Jul 20, 2011 at 8:42 AM, Kyle Lemons <kev...@google.com> wrote:
Without conditional compilation, it is "impossible" to write a piece of Go code which will be interpreted differently by (the same compiler on) another system, which vastly increases the confidence a developer can have in his application on a target system.  If we added them, then people would ask for command-line #defines and then someone would write ./configure and then where would we be?

I wasted three hours I should've been sleeping last night instead chasing #ifdefs in a C project's headers and sources, trying to figure out wth was actually being compiled.

I love just reading Go code and knowing what will happen.

Alex Ray

unread,
Jul 20, 2011, 12:51:54 PM7/20/11
to Kyle Lemons, andrey mirtchovski, golang-nuts
What I was looking for was a way to break compilation partway through on a conditional, NOT conditional compilation (yes i do know all the horrible nasty breaks that causes).

This short circuit could save you compiling the remainder of a (very) large project, and running through the testing suite.

In retrospect, as long a build times stay small, even for large projects, the suitable answer (to me) is just let it compile and run into testing and fail with an informative message there. It doesnt have any syntactic representation in the source (just in the test), but could be in comments. e.g. // dont set this to less than 2

looks like i overflowed the bad idea list
~Alex

Kyle Lemons

unread,
Jul 20, 2011, 1:07:53 PM7/20/11
to aj...@ncsu.edu, andrey mirtchovski, golang-nuts
What I was looking for was a way to break compilation partway through on a conditional, NOT conditional compilation (yes i do know all the horrible nasty breaks that causes).

What purpose would this have without preprocessor conditionals?  I have only seen #error or #pragma error used in projects when some combination of -Ds doesn't work or if some feature is unavailable on the system and configure wasn't able to tell it was necessary or something.
 
This short circuit could save you compiling the remainder of a (very) large project, and running through the testing suite.

It's often important to structure testing such that small tests are run first and longer tests are run later; if you have tests that are likely to fail for some reason, try to get them to run first. One way to accomplish this is with the "short test" mechanism in gotest.

John Beshir

unread,
Jul 20, 2011, 1:57:42 PM7/20/11
to golan...@googlegroups.com

Split it into separate files and do it in the build system. Nicer
organised when one file is always entirely in or out of the build, and
avoids the need for a preprocessor, but can do the same job.

Reply all
Reply to author
Forward
0 new messages