Thread: need help with extern pointers.

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    87

    need help with extern pointers.

    Please help me in my program here. i started using extern pointers in my project and all the mess started. Prior to this I was simply passing double pointers to variables or returning them to propogate them from one function to other. However, usin extern, although difficult, seems very lucrative because then you don't have to worry too much about double pointers or returning stuff.

    Code:
    /* READER.H */
    
    #ifndef reader_h
    #define reader_h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define SUCCESS 0
    #define FAILURE 1
    
    typedef struct vector_struct
    {
         double x, y, z;
    
    }vector;
    typedef vector vertex;
    
    typedef struct triangle_struct
    {
      vector a, b, c;
      vector n;
    
    }triangle;
    
    typedef struct object_struct
    {
      int nvert,ntri;
      vertex *vert;
      triangle *tri;
    
    }object;
    
    extern object *obj       /* PLEASE TAKE A NOTE OF THIS ! */
    
    int reader(object *);
    
    #endif

    if you want, you might skip this code because i have executed it before using the extern keyword and it executed fine meaning that there is nothing logically wrong with it just some problem with extern object pointer perhaps.

    Code:
    #include "reader.h"
    
    int reader(object *obj)
    {
    	enum
            {
    	      FIRST_LINE,
                  SECOND_LINE,
                  THIRD_LINE,
                  FOURTH_LINE,
                  VERTICES,
                  GAP,
                  TRIANGLES,
                  LAST_LINE
    
            } state;
    
        
         int vertex_count = 0;
         int triangle_count = 0;
         FILE *zeus_file;
         char data_line[120];
       
         state = FIRST_LINE;
         zeus_file = fopen("sphere.zeus", "r");
    
         if(zeus_file == NULL)
         {
                   perror(" File open error!");
    	       return FAILURE;
         }
    
    	obj = malloc(sizeof(object));/* ALLOCATED MEMORY. BEFORE OBJ WAS NULL */
    	
        while (state != LAST_LINE) 
        {
                      
                  
    		if (fgets(data_line, 120, zeus_file) == NULL) 
                  {
    			perror("zeus file read failed");
                            return FAILURE;
                  }
                 switch (state) 
                 {
    			     case (FIRST_LINE):
                 			    /* do nothing */
                 		           state = SECOND_LINE;
                 			    break;
                                 case (SECOND_LINE):
                 			    /* do nothing */
                                    state = THIRD_LINE;
                                    break;
             			case (THIRD_LINE):
                			    sscanf(data_line, "%d %*d %d", &obj->nvert, &obj->ntri);
                                     obj->vert = calloc(sizeof(vertex), obj->nvert);
                                     obj->tri = calloc(sizeof(triangle), obj->ntri);
    				   if( obj->vert == NULL || obj->tri == NULL)
    				   {
    					perror("Memory cannot be allocated!");
    					return FAILURE;
    				   }
                                    state = FOURTH_LINE;
                                    break;
                                 case (FOURTH_LINE):
                                    /* do nothing */
                                   state = VERTICES;
                                   break;
             			case (VERTICES):
                			  sscanf(data_line, "%lf %lf %lf",&obj->vert[vertex_count].x,&obj->vert[vertex_count].y,&obj->vert[vertex_count].z);
                                   vertex_count += 1;
                                   if (vertex_count >=  obj->nvert) 
    					state = GAP;
                                  break;
                                case (GAP):
    	                       state = TRIANGLES;
                                   break;
                                case (TRIANGLES):
                                  sscanf(data_line, "%d %d %d",&obj->tri[triangle_count].v0,&obj->tri[triangle_count].v1,&obj->tri[triangle_count].v2);
                                  triangle_count += 1;
                                  if (triangle_count >= obj->ntri )
    					state = LAST_LINE;
    				 break;
                  }
    
         }
    
      return SUCCESS;                                                                                                                                                               
    
    }


    Now in my main.c :

    Code:
    #include "reader.h"
    
    object *obj = NULL; /* DEFINED THE EXTERN POINTER VARIABLE */
    
    int main(void)
    {
      int i; 
       i = reader(obj)
       if(i == FAILURE)
         printf(" program failed \n");
      
      else
      {
    
            printf("Number of vertices: %d   Number of triangles: %d", obj->nvert, obj->ntri);
           /* Program is hanging here */
    
       }
    
       return 0;
    
    }

    please tell me what is going on.

    Also, when you declare a pointer as extern, is it true that its most uptodate value will be available everywhere and the contents to which it points to are not destroyed unless the whole program(i.e. all modules) gets terminated.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Extern does nothing more than tell the compiler that a specific variable was defined elsewhere - in another source file. Otherwise the compiler would complain that the variable hasn't been defined.
    And your previous way was better because you're using a global variable now, which is very error prone.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You have a global pointer named obj, and you pass it to reader(). reader()'s parameter is named obj, so it hides the global pointer named obj. As such, the memory allocated is to a local pointer named obj. The obj visible to main() remains NULL.

    I think that avoiding another level of indirection is not a good reason to use a global variable.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by laserlight View Post
    You have a global pointer named obj, and you pass it to reader(). reader()'s parameter is named obj, so it hides the global pointer named obj. As such, the memory allocated is to a local pointer named obj. The obj visible to main() remains NULL.

    I think that avoiding another level of indirection is not a good reason to use a global variable.
    It's not that I want to avoid another level of indirection but actually its become a necessity to use external variables in my project. MY project has crossed 800 lines or so and there are certain things which I want to make global so that the need of having to pass them to every function is eradicated.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You need to weight the consequences of that. Global variables are error prone.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by broli86 View Post
    It's not that I want to avoid another level of indirection but actually its become a necessity to use external variables in my project. MY project has crossed 800 lines or so and there are certain things which I want to make global so that the need of having to pass them to every function is eradicated.
    Probably not a good idea. Using global variables to AVOID passing them is almost never a valid excuse.

    If you have MANY variables that you almost always pass around together, then using a struct that puts all of them "in one place" is perhaps a solution.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Btw, I followed laserlight's advice and removed the obj passed in call to reader..

    i = reader();

    I changed the prototype to int reader();

    And now the thing is it is working perfectly.

    I want this object to be seen everywhere so I guess I do need to make it global. What do yo all suggest ?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by broli86 View Post
    Btw, I followed laserlight's advice and removed the obj passed in call to reader..

    i = reader();

    I changed the prototype to int reader();

    And now the thing is it is working perfectly.

    I want this object to be seen everywhere so I guess I do need to make it global. What do yo all suggest ?
    See my previous comment. No globals.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by Elysia View Post
    You need to weight the consequences of that. Global variables are error prone.
    in what way ?

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by matsp View Post
    Probably not a good idea. Using global variables to AVOID passing them is almost never a valid excuse.

    If you have MANY variables that you almost always pass around together, then using a struct that puts all of them "in one place" is perhaps a solution.

    --
    Mats
    How about the fact that I want it to be visible everywhere ? I only want to declare those variables as extern whose values will not alter throughout the program.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why do you want it "visible everywhere"? What are you doing with it?

    How many functions are we talking about that needs this object?

    Will you ever need other global objects?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by broli86 View Post
    in what way ?
    Wait -- you started a thread because your program broke due to global variables, and you're asking how they cause errors?

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tabstop View Post
    Wait -- you started a thread because your program broke due to global variables, and you're asking how they cause errors?
    Actually, technically, it broke due to "global variable hidden by local" - but I agree it's a bit strange.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by broli86 View Post
    How about the fact that I want it to be visible everywhere ? I only want to declare those variables as extern whose values will not alter throughout the program.
    You sound like esbo
    That's exactly what makes them bad - any function can see, read and write to it, causing unexpected behaviour and makes you scratch your head wondering where that variable is defined, what and where it's used, etc.
    If there's a constant value somewhere, define it as a constant variable in a header and include it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    My project is some numerical computation based on ray tracing. I figured out a few things which should probably have a global scope:

    1. Source and Receiver locations - After the user enters them,
    unlikely to change for one complete computation. Needed everywhere for
    ray computations.

    2. Object Specification - After the particular object has been read
    from the ASCII file, it will not change for one complete computation.
    This information is also crucial because you are ray tracing against
    object itself.

    3. Kd tree - You need it while traversing the rays. Doesn't look good
    to pass the root pointer every where all the time.

    Apart from these three, there is nothing in my program that needs to
    have global scope.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Headers that use each other
    By nickname_changed in forum C++ Programming
    Replies: 7
    Last Post: 10-03-2003, 04:25 AM
  2. Extern Question, really confused
    By SourceCode in forum C Programming
    Replies: 10
    Last Post: 03-26-2003, 11:11 PM
  3. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM
  4. extern symbols, what do these mean exactly?
    By Shadow12345 in forum C++ Programming
    Replies: 8
    Last Post: 11-02-2002, 03:14 PM
  5. extern keyword and structures
    By GuitGentlyWeeps in forum C Programming
    Replies: 2
    Last Post: 01-30-2002, 07:02 AM