Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Pass a struct as a function parameter or just use it as a global variable?

Pass a struct as a function parameter or just use it as a global variable?

Scheduled Pinned Locked Moved C / C++ / MFC
questiondiscussion
3 Posts 2 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vaclav_
    wrote on last edited by
    #1

    Yet another one of my favourites - academic questions. Hopefully a decent discussion will follow, but please no more RTFM. Cheers

    K 1 Reply Last reply
    0
    • V Vaclav_

      Yet another one of my favourites - academic questions. Hopefully a decent discussion will follow, but please no more RTFM. Cheers

      K Offline
      K Offline
      k5054
      wrote on last edited by
      #2

      Unless you have a good, compelling argument otherwise (and there are a few), you should prefer to pass structs as parameters. If its small (e.g. something like a struct timeval), and you don't need to modify the members, its OK to pass by value. If its large, then pass by reference (pointer). If you're not going to modify the struct in the function then you should mark the reference as const.

      struct small_obj {
      char description[16];
      int count;
      }; // size = 20 bytes

      struct large_obj {
      char text[1024][1024];
      double factor[1024][1024];
      }; // size = 9 MB

      void f1(small_obj arg); // OK, puts 20 bytes on the stack, f1 gets a copy
      // of the struct. Any modifications to the struct are
      // local ot f1

      void f2(small_obj* arg); // stack is 4 bytes only. changes to f2 members will not
      // be seen by caller

      void f3(const small_obj *arg); // stack is 4 bytes only. attempts within f3 to modify members
      // should produce compiler warnings

      void f4(small_obj& arg); // similar to f2(), but uses C++ reference type

      void f5(const small_obj& arg); // similar to f3, but uses C++ reference type

      void f6(large_obj arg); // questionable. This copys 9 MB onto the stack, which might
      // be more than the OS can handle, and might incur performance
      // penalties you can avoid by passing as a pointer or reference

      The problem with global values, especially global values that are not local to a single file (e.g. declared as static), is it becomes increasingly more difficult to reason about where the variable gets modified. Given a function say print_item(void) you might not expect your global Item to get modified, but print_item() calls foo(void), which calls bar(void) which calls frobnicate(void), which modifies Item. If you are trying to trace down a bug, trying to see where Item gets modified can be difficult. On the other hand, calling print_item(const Item&), you can be (more or less) sure that Item doesn't get modified during the lifetime of print_item() (more or less because print_item() could be nasty and cast away constness, but that's an evil for another tale). Alternatively, you might have print_item(Item foo), which gets a local copy of Item, so the caller knows that whatever changes print_item might make to its copy, the callers Item remains unchan

      V 1 Reply Last reply
      0
      • K k5054

        Unless you have a good, compelling argument otherwise (and there are a few), you should prefer to pass structs as parameters. If its small (e.g. something like a struct timeval), and you don't need to modify the members, its OK to pass by value. If its large, then pass by reference (pointer). If you're not going to modify the struct in the function then you should mark the reference as const.

        struct small_obj {
        char description[16];
        int count;
        }; // size = 20 bytes

        struct large_obj {
        char text[1024][1024];
        double factor[1024][1024];
        }; // size = 9 MB

        void f1(small_obj arg); // OK, puts 20 bytes on the stack, f1 gets a copy
        // of the struct. Any modifications to the struct are
        // local ot f1

        void f2(small_obj* arg); // stack is 4 bytes only. changes to f2 members will not
        // be seen by caller

        void f3(const small_obj *arg); // stack is 4 bytes only. attempts within f3 to modify members
        // should produce compiler warnings

        void f4(small_obj& arg); // similar to f2(), but uses C++ reference type

        void f5(const small_obj& arg); // similar to f3, but uses C++ reference type

        void f6(large_obj arg); // questionable. This copys 9 MB onto the stack, which might
        // be more than the OS can handle, and might incur performance
        // penalties you can avoid by passing as a pointer or reference

        The problem with global values, especially global values that are not local to a single file (e.g. declared as static), is it becomes increasingly more difficult to reason about where the variable gets modified. Given a function say print_item(void) you might not expect your global Item to get modified, but print_item() calls foo(void), which calls bar(void) which calls frobnicate(void), which modifies Item. If you are trying to trace down a bug, trying to see where Item gets modified can be difficult. On the other hand, calling print_item(const Item&), you can be (more or less) sure that Item doesn't get modified during the lifetime of print_item() (more or less because print_item() could be nasty and cast away constness, but that's an evil for another tale). Alternatively, you might have print_item(Item foo), which gets a local copy of Item, so the caller knows that whatever changes print_item might make to its copy, the callers Item remains unchan

        V Offline
        V Offline
        Vaclav_
        wrote on last edited by
        #3

        Thanks, you may have answered my other problem. ( I'll posting it soon.) At this point I use struct sort-off attached to a class. Not static. I am saying sort-off because the main code is OpenGL and it does not work well in C++ class. I do not foresee any other code to modify it. But for learning experience I'll go with passing the struct via pointer to the function which is also "passed" as parameter to another function. Pretty convoluted , mostly because OpenGL "pipe" architecture. But so far it id working as expected.

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups