Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to read a file at compile time?

Tags:

c++

c++11

c++14

I am wondering if it is possible in C++11/14 to actually read files at compile time. For example the following code will only compile if it can successfully read the file.

constexpr std::string shader_source = load("~/foo.glsl"); 

Do you think this could be possible?

I know that I could do this with some custom tool when building my application.

like image 815
Maik Klein Avatar asked Oct 02 '14 13:10

Maik Klein


People also ask

What is checked at compile time?

Compile-time checking occurs during the compile time. Compile time errors are error occurred due to typing mistake, if we do not follow the proper syntax and semantics of any programming language then compile time errors are thrown by the compiler.

What happens when a file is compiled?

The Compiler creates the intermediate code file during its first phase, when it checks the program syntax. The Compiler also creates a dictionary file, which is used by the debugger. Intermediate code files compile quickly. Intermediate code files have the extension .

What is compile time?

In computer science, compile time (or compile-time) describes the time window during which a computer program is compiled. The term is used as an adjective to describe concepts related to the context of program compilation, as opposed to concepts related to the context of program execution (runtime).

Why is compile time faster?

Also the compiler will internally used optimized code. And it will convert the nonesense recursive approach to an iterative approach. And to calculate that values will take less time than the compiler overhead functions. So, that is the real reason.


1 Answers

Building on teivaz's idea, I wonder if the usual "stringize after expansion" trick will work:

#define STRINGIZE(...) #__VA_ARGS__ #define EXPAND_AND_STRINGIZE(...) STRINGIZE(__VA_ARGS__)  constexpr std::string shader_source = EXPAND_AND_STRINGIZE( #include "~/.foo.glsl" ); 


Still, I would go for a conventional extern const char[] declaration resolved to the content by the linker. The article "Embedding a File in an Executable, aka Hello World, Version 5967" has an example:

# objcopy --input binary \           --output elf32-i386 \           --binary-architecture i386 data.txt data.o 

Naturally you should change the --output and --binary-architecture commands to match your platform. The filename from the object file ends up in the symbol name, so you can use it like so:

#include <stdio.h>  /* here "data" comes from the filename data.o */ extern "C" char _binary_data_txt_start; extern "C" char _binary_data_txt_end;  main() {     char*  p = &_binary_data_txt_start;      while ( p != &_binary_data_txt_end ) putchar(*p++); } 
like image 189
Ben Voigt Avatar answered Sep 20 '22 21:09

Ben Voigt