I wrote small convenience functions for working with environment variables in C++ by wrapping std::getenv
, setenv
and environ
. In addition to setting and getting the environment variables, I provided functionality to check if the current environment contains a certain variable.
#include <cstdlib>
#include <unistd.h>
template <typename VAR_TYPE>
void set(const std::string& variableName, VAR_TYPE varValue, bool overwrite = false) {
if (!setenv(variableName.c_str(), std::string(variableValue).c_str(), overwrite)) {
if (errno == ENOMEM) {
throw std::bad_alloc();
} else if (errno == EINVAL) {
throw std::invalid_argument("Variable name invalid: " + variableName);
} else {
throw std::runtime_error("Failed to set environment variable " + variableName);
}
}
}
std::string load(const std::string& variableName, const std::string& defaultValue = "") {
if (const char* envVariable = std::getenv(variableName)) {
return std::string(envVariable);
}
return defaultValue;
}
bool contains(const std::string& variableName) {
for (char** currentEnviron = environ; *currentEnviron; currentEnviron++) {
if (!std::strncmp(variableName.c_str(), *currentEnviron, variableName.length())) {
return true;
}
}
return false;
}
However, by definition, this only allows to access environment variables that are in the form NAME=VALUE
.
In bash
, I can do the following:
$> export SOME_VAR
$> export -p | grep SOME_VAR
declare -x SOME_VAR
Apparently, SOME_VAR
is defined somewhere, even if I dont assign a value to it. When I run printenv
however, which uses the same methods I use in my wrapper, SOME_VAR
is not listed. I have had a look at /proc/self/environ
but this only lists variables with assigned value.
My questions are:
- What is the difference between an environment variable defined as
SOME_VAR_WITH_VALUE=42
andSOME_VAR_WITHOUT_VALUE
. - Is there a possibility in C/C++ to access environment variables without values?