Comments (2)
When an if statement is analyzed, the condition is checked for constant expression evaluation. If the condition is available at compile time, then this if statement becomes a conditional compilation construct. Combine this with a compiler function which checks compile information, and we're already almost done:
fn f() {
if (#compile_var("os") == "linux") {
// ...
} else {
// ...
}
}
#compile_var()
can look up a string in a table of variables defined at compile time. A compile variable might be any type.
Usually, if an if condition's "then" expression or "else" expression is unreachable because the condition is constant, it will generate an "unreachable code" error. However, we can annotate the constant expression with a value indicating that it can differ depending on compile time variables. When this annotation is present, the "unreachable code" error is not generated.
So, conditional compilation is perfectly integrated into the language's syntax within a function. Let's look at outside a function:
const foo : i32 = if (#compile_var("release")) 1234 else 5678;
Global constants and variables can use full expression syntax for their initializers, so this works here too.
How about a global initialized list of things (example), of which the length of the list is dependent on compile time variables?
In C we have:
static const enum SoundIoBackend available_backends[] = {
#ifdef SOUNDIO_HAVE_JACK
SoundIoBackendJack,
#endif
#ifdef SOUNDIO_HAVE_PULSEAUDIO
SoundIoBackendPulseAudio,
#endif
#ifdef SOUNDIO_HAVE_ALSA
SoundIoBackendAlsa,
#endif
#ifdef SOUNDIO_HAVE_COREAUDIO
SoundIoBackendCoreAudio,
#endif
#ifdef SOUNDIO_HAVE_WASAPI
SoundIoBackendWasapi,
#endif
SoundIoBackendDummy,
};
In Zig we take advantage of void
array elements being removed from the array:
const available_backends = [
if (#compile_var("have_jack")) SoundIoBackend.Jack else void,
if (#compile_var("have_pulse_audio")) SoundIoBackend.PulseAudio else void,
if (#compile_var("have_alsa")) SoundIoBackend.Alsa else void,
if (#compile_var("have_core_audio")) SoundIoBackend.CoreAudio else void,
if (#compile_var("have_wasapi")) SoundIoBackend.Wasapi else void,
SoundIoBackend.Dummy,
];
Note that technically the else void
could be omitted since an if statement with no else defaults to else void
. It may be that void
is the wrong type for this, but this construct is powerful and so if void
is the wrong type then we may introduce a "deleted array item" type.
Next problem. Anything that you can export, you might want to not export it. So, for any top level declaration for which export
is valid - this currently includes functions, global variables, enums, and structs, we will also define a directive, let's call it #condition()
which accepts a boolean expression which decides if the top level declaration is included in the compilation. If the top level declaration is not included, then calling it or otherwise depending upon it is a compile time error. Example:
#condition(#compile_var("os") == "win32")
export fn trace_win32() {
const err = get_last_win32_error();
print_win32_error(err);
}
fn f1() {
if (#compile_var("os") == "win32") {
trace_win32(); // OK, since const expression eval ensured this didn't actually run when trace_win32 is not exported
}
trace_win32(); // error when building with compile var "os" == "win32": trace_win32 symbol not defined
}
Finally the only problem left is the syntax that we use to import C .h files. We don't yet have a syntax for directly importing a C .h file, but it's planned. We would need to conditionally import some .h files and not others depending on compile variables. I'll defer figuring out how that will work until we actually have that construct. But I will mention that it's probably planned that the best use of the auto C .h file importing feature is to limit it to a single invocation that would declare the order in which preprocessor defines are defined and what their values are as well as the order of (virtual) #include
s. So, one could associate preprocessor defines with expressions and #include
s with boolean expressions.
from zig.
This all works now.
from zig.
Related Issues (20)
- build runners are cached causing overrides to be ignored
- Allow modules to have private and public include directories
- Zig's static analysis for undefined memory access doesn't error where C++'s tooling does error HOT 6
- shift an integer by 32 gives error HOT 3
- Panicked during panic during building zig hello world project HOT 1
- Function pointer to inline function causes linker error HOT 3
- Function pointer call in C macro doesn't get unwrapped
- eliminate absolute paths from the build system HOT 1
- `Dir.makePath` handles `..` in the sub_path differently per-platform HOT 3
- lldb control flow branch-skip unexpectely ends **inside** control flow block HOT 4
- [windows, 0.12-dev] error: root struct of file 'zig.system' has no member named 'NativeTargetInfo' HOT 2
- build: probabilistic inconsistent cache state on Windows (repeatedly AccessDenied) from modifying build.zig during running `zig build runcmiti` HOT 1
- C source file of module dependency has wrong path
- compiler crash lowering extern pointer to any opaque (recently working) HOT 8
- cannot bitcast from enum to packed struct HOT 4
- zig MSVC target: undefined symbol HOT 3
- Compiler can't fetch shared library with version on it ! ( libfoo.so.x.y ) HOT 3
- lldb control flow branch-skip unexpectely ends **inside** control flow block
- `@addWithOverflow` is slower than `std.math.add` even though builtins should be preferred over stdlib functions HOT 11
- Zig errors on not finding c header files, but works if the include path parameter is after --mod param in cli HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zig.