where is the definition of extern char **environ? - c

we can get the environment variable in C like this:
extern char **environ;
int main(int argc, char *argv[])
{
int count = 0;
printf("\n");
while(environ[count] != NULL)
{
printf("[%s] :: ", environ[count]);
count++;
}
return 0;
}
but where is the defination of environ? I can't find that in unistd.h. and how does it work?

environ is defined as a global variable in the Glibc source file posix/environ.c.

Have you tried declaring envp as parameter to main?
int main (int argc, char *argv[], char *envp[])
http://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html#Program-Arguments

man:
This variable must be declared in the user program, but is declared in the header file unistd.h in case the header files came from libc4 or libc5, and in case they came from glibc and _GNU_SOURCE was defined.

On POSIX systems, the identifier
extern char **environ;
does not have to be defined in any header. As noted in #triclosn's answer to this question, "This variable must be declared in the user program ..."
Per POSIX 7 Environment Variables:
The value of an environment variable is a string of characters. For a C-language program, an array of strings called the environment shall be made available when a process begins. The array is pointed to by the external variable environ, which is defined as:
extern char **environ;
There is no POSIX requirement that the environ variable be declared in any header file, so on a POSIX-compliant system it's just available should you wish to declare it in your code.

Related

Statement: " There must be at least one statement in the executable part in main function."

My textbook mentions: There must be at least one statement in the executable part of main function.
1)
#include <stdio.h>
void main(){ int c; }
2)
#include <stdio.h>
void main(){ int c; c=0; }
The above two codes result in runtime error.
3)
#include <stdio.h>
void main(){
int c; c=5; printf("%d",c); }
The above code runs fine. What is the possible reason?
First,
1 The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters: int main(void) { /* ... */ } or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined manner.
C 2011 Online Draft, §5.1.2.2.1 Program Startup
Unless your compiler documentation specifically lists it as a valid signature, using void main() leads to undefined behavior, which may be where your runtime errors are coming from.
Secondly, the current C standard does not require that main contain any executable statements.

Is there a way to determine if LC_CTYPE is set in C?

Using C, is there a way to find out if LC_CTYPE is set? I am rewriting printf and my %lc needs to work differently depending on if the locale is set.
LC_CTYPE is an environment variable. You can use any of the normal methods of accessing environment variables, which differ based on platform. For example, POSIX's third envp argument to main:
int main(int argc, char **argv, char **envp);
or the standard C89 getenv() function:
char *getenv(const char *name);
For example:
#include <stdlib.h>
char const *get_lc_ctype()
{
return getenv("LC_CTYPE");
}
Be careful not to modify strings returned by getenv(3), that is undefined behaviour. If you want to set LC_CTYPE, you should use the (POSIX-standardised but not C-standardised) setenv(3):
int set_lc_ctype(char const *new)
{
return setenv("LC_CTYPE", new, 1);
}
A generic way is to use 'setlocale()'.
From the man page:
If locale is an empty string, "", each part of the locale that should be modified is set according to the
environment variables.
Thus, you get LC_TYPE by
#include <locale.h>
// ...
char* lc_type= setlocale(LC_CTYPE, "");

How to read environment variable in Glibc code

I want to disable/enable printf() output to screen by reading an environment variable, similar to how LD_DEBUG works.
I want to control ./stdio-common/printf.c.
So if in environment variable says disable printf() it call
int
__printf (const char *format, ...)
{
return done;
}
else it executes the original code. How would I implement this?
Use getenv. See getenv(3) for details.
The recommended way is to use the solution provided by ANSI as getenv() function for maximum portability:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char * env = getenv(“PROMPT”));
if(env)
puts(env);
else
puts(“The environmental variable not available”);
return 0;
}
There are other non-standard ways of doing the same which is not recommended.
The third argument to main() could be char **envp is used widely to get the information about the environment and is non-standard.
int main(int argc, char **argv, char **envp)
{
while(*envp)
printf("%s\n",*envp++);
}
Using the third argument in main() is not strictly conforming to standard.
There is another widely used non-standard way of accessing the environmental variables and that is through the environ external variable.
int i=0;
extern char ** environ;
while(environ[i])
printf("\n%s",environ[i++]);
NOTE: The examples are in-complete and lacks error handling.

Extern Variable

int main()
{
extern int i;
i=20;
printf("%d",i);
return 0;
}
The compiler is giving an Error that 'i' is undefined
Whats the Reason?
Difference :
1.int i; // i is defined to be an integer type in the current function/file
2.extern int i; // i is defined in some other file and only a proto-type is present here.
Hence while compiling, the compiler(LDD) will look for the original definition of the variable and if it does'nt find, it'll throw an error 'undefined reference to `i'.
By saying extern you tell the compiler that i is defined in a different translation unit, which I'm guessing you don't have. There's a difference between declaration and definition in C. In short, the former is telling the compiler the type of the variable, the latter is telling to allocate storage for it.
Just drop that extern for now.
i has no storage location.
You must link with a translation unit that includes int i; (not extern).
extern
Allows one module of your program to access a global variable or function declared in another module of your program.
You usually have extern variables declared in header files.
If you don't want a program to access your variables or functions, you use static which tells the compiler that this variable or function cannot be used outside of this module.
errno.h
#ifndef ERRORS /* prevent multiple inclusion */
#define ERRORS 0
extern int errno; <- Declaring the variable to be external.
extern void seterrorcode(int errcode);
#endif
errno.c
#include "errno.h"
int errno; <- This is where the definition of errno occurs
static int stuff; <- This is private to this module.
void seterrorcode(int errcode)
{
errno = errcode;
}
main.c
#include "errno.h"
/* extern int stuff : This line will produce an undefined variable error when linking */
int main()
{
seterrorcode(0);
if (errno > 0)
; /* Error code > 0, do something */
}
For more Info
extern keyword is used to tell the compiler that the variable
is defined in another file
but during linking, the linker does not resolve the variable
so you get an error
1.For this question,you need to understand that definition is a superset of declaration.In declaration,we just introduce the variable that is going to be used but do not allocate any memory to it.But in the case of definition,we both declare and allocate memory to the variable.
2.int i;
This sentence will both declare and define the variable i
3.On the other hand
extern int i;
This sentence will just extend the visibility of the variable to the whole program.Effectively,you are just defining the variable and not declaring it.
i=20;
this line is trying to assign 20 to a variable that does not exist.
4.It can be corrected by writing
extern int i=20;
Hope this helps!

extern and global in c

Can anyone please tell me is there any special requirement to use either EXTERN or GLOBAL variables in a C program?
I do not see any difference in a program like below, if I change from gloabl to extern.
#include <stdio.h>
#include <stdlib.h>
int myGlobalvar = 10;
int main(int argc, char *argv[])
{
int myFunc(int);
int i;
i = 12;
myGlobalvar = 100;
printf("Value of myGlobalvar is %d , i = %d\n", myGlobalvar, i);
i = myFunc(10);
printf("Value of passed value : %d\n",i);
printf("again Value of myGlobalvar is %d , i = %d\n", myGlobalvar, i);
system("PAUSE");
return 0;
}
int myFunc(int i)
{
i = 20 + 1000;
//extern int myGlobalvar;
myGlobalvar = 20000;
// printf("Value of passed value : %d",i);
return i;
}
If uncomment extern int myGlobalvar, the value does not change.
Is there any correct difference between both?
Can anyone please correct me?
The keyword extern means "the storage for this variable is allocated elsewhere". It tells the compiler "I'm referencing myGlobalvar here, and you haven't seen it before, but that's OK; the linker will know what you are talking about." In your specific example it's not particularly useful, because the compiler does know about myGlobalvar -- it's defined earlier in the same translation unit (.c or .cc file.) You normally use extern when you want to refer to something that is not in the current translation unit, such as a variable that's defined in a library you will be linking to.
(Of course, normally that library would declare the extern variables for you, in a header file that you should include.)
From Here:
A global variable in C/C++ is a variable which can be accessed from any module in your program.
int myGlobalVariable;
This allocates storage for the data, and tells the compiler that you want to access that storage with the name 'myGlobalVariable'.
But what do you do if you want to access that variable from another module in the program? You can't use the same statement given above, because then you'll have 2 variables named 'myGlobalVariable', and that's not allowed. So, the solution is to let your other modules DECLARE the variable without DEFINING it:
extern int myGlobalVariable;
This tells the compiler "there's a variable defined in another module called myGlobalVariable, of type integer. I want you to accept my attempts to access it, but don't allocate storage for it because another module has already done that".
Since myGlobalvar has been defined before the function myFunc. Its declaration inside the function is redundant.
But if the definition was after the function, we must have the declaration.
int myFunc(int i)
{
i = 20 + 1000;
extern int myGlobalvar; // Declaration must now.
myGlobalvar = 20000;
printf("Value of passed value : %d",i);
return i;
}
int myGlobalvar = 10; // Def after the function.
In short: GLOBAL variables are declared in one file. But they can be accessed in another file only with the EXTERN word before (in this another file). In the same file, no need of EXTERN.
for example:
my_file.cpp
int global_var = 3;
int main(){
}
You can access the global variable in the same file. No need to use EXTERN:
my_file.cpp
int global_var = 3;
int main(){
++global_var;
std::cout << global_var; // Displays '4'
}
Global variable, by definition, can also be accessed by all the other files.
BUT, in this case, you need to access the global variable using EXTERN.
So, with my_file.cpp declaring the global_var, in other_file.cpp if you try this:
other_file.cpp
int main(){
++global_var; // ERROR!!! Compiler is complaining of a 'non-declared' variable
std::cout << global_var;
}
Instead, do:
int main(){
extern int global_var;//Note: 'int global_var' without 'extern' would
// simply create a separate different variable
++global_var; // and '++global_var' wouldn't work since it'll
// complain that the variable was not initiazed.
std::cout << global_var; // WORKING: it shows '4'
}
myGlobalVar as you've defined it is a global variable, visible from all the places in your program. There's no need declaring it extern in the same .c file . That is useful for other .c files to let the compiler know this variable is going to be used.

Resources