Thread: Messing with header files

  1. #16
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Now that's an idea! Make global variables that can't be accessed as global variables. Scattering is the point of global variables
    Yeah, but they can live a little bit longer than even the main function... So you should not worry that the memory will be freed before your program is finished...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  2. #17
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Quote Originally Posted by Daved
    BTW, use of static for this purpose is deprecated in favor of the unnamed namespace.
    But is there any case where you would want to put a non-const with file scope in a header file? In that case the compiler would generate a different variable for each compilation unit.

    I thought the purpose of an unnamed namespace was to keep a variable from one .cpp file from being used in another (via the extern keyword), e.g.
    Code:
    //foo.cpp
    namespace
    {
      int foo;
    }
    
    //main.cpp
    extern int foo; 
    //any attempt to use foo results in linker errors
    And isn't there also some advantage to using unnamed namespaces over the static keyword? (because those variables have external linkage, whereas variables delcared at file scope with the static keyword have internal linkage)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #18
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The net effect of using static and unnamed namespaces is exactly the same. The advantages are:
    1) Less to type: you don't have to repeat "static" for every symbol.
    2) Static, as used on the file level, is misnamed. It's better not to use it for that reason.
    (Although ... the unnamed namespace thing isn't exactly intuitive ...)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #19
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    But, like I said, statics have internal linkage, whereas objects in unnamed namespaces have external linkage. After some perusing, I think I finally see the difference:
    Code:
    template <const int& T> struct xyz { };
    
    static int c = 1;
    xyz<c> y; // error!
    
    namespace
    {
      int c = 1;
    }
    xyz<c> y; //ok
    (see http://www.comeaucomputing.com/techtalk/#nostatic)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  5. #20
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Now I made a class inside a new header file and included it from main.h:
    Code:
    #pragma once
    #define _WIN32_IE 0x601
    #include <windows.h>
    #include <richedit.h>
    #include <commctrl.h>
    #include "listview.h"
    
    #define N_OTSI WM_USER+666
    
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    extern char szClassName[];
    extern HINSTANCE hinst;
    extern HWND controls[10];
    extern MyLVC list;
    The header with class includes main.h and has the class defined in it.
    I get those multiple definition things again.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  6. #21
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    if you use
    Code:
    #ifndef MYHEADER
    #define MYHEADER
    extern char hello[];
    #endif
    I don't see what can be a problem

    Could you provide a header with errors?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #22
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Four files in my project:
    main.cpp
    Code:
    #include "main.h"
    
    int WINAPI WinMain(HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil){
    	HWND hwnd;
    	MSG messages;
    	WNDCLASSEX wincl;
    	HINSTANCE RichDLL;
    	hinst=hThisInstance;
    	RichDLL=LoadLibrary("msftedit.dll");
    	wincl.hInstance = hThisInstance;
    	wincl.lpszClassName = szClassName;
    	wincl.lpfnWndProc = WindowProcedure;
    	wincl.style = CS_DBLCLKS;
    	wincl.cbSize = sizeof (WNDCLASSEX);
    	wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    	wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    	wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    	wincl.lpszMenuName = NULL;
    	wincl.cbClsExtra = 0;
    	wincl.cbWndExtra = 0;
    	wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    	InitCommonControls();
    
    	if (!RegisterClassEx (&wincl)){
    		return 0;
    	}
    
    	hwnd=CreateWindowEx(0,szClassName,"Dictionary",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,544,
    		375,HWND_DESKTOP,NULL,hThisInstance,NULL);
    	ShowWindow (hwnd, nFunsterStil);
    
    	while (GetMessage (&messages, NULL, 0, 0)){
    		TranslateMessage(&messages);
    		DispatchMessage(&messages);
    	}
    	return messages.wParam;
    }
    
    LRESULT CALLBACK WindowProcedure(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
    	switch (message){
    		case WM_CREATE:
    			controls[0]=CreateWindowEx(WS_EX_CLIENTEDGE,"RichEdit50W",NULL,WS_CHILD|WS_VISIBLE,
    				3,0,100,100,hwnd,(HMENU)300,hinst,NULL);
    			list.Init(106,10,400,120,hwnd,300,LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP);
    			list.SetDefaultColumnStyle(LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH|LVCF_FMT,LVCFMT_LEFT);
    			list.AddColumn("First",150);
    			list.AddColumn("Second",250);
    			break;
    		case WM_COMMAND:
    			
    			break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			break;
    		default:
    			return DefWindowProc(hwnd,message,wParam,lParam);
    	}
    	return 0;
    }
    main.h
    Code:
    #ifndef H_MAIN
    #define H_MAIN
    #define _WIN32_IE 0x601
    #include <windows.h>
    #include <richedit.h>
    #include <commctrl.h>
    #include "listview.h"
    
    #define N_OTSI WM_USER+666
    
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    extern char szClassName[];
    extern HINSTANCE hinst;
    extern HWND controls[10];
    extern MyLVC list;
    #endif
    global.cpp
    Code:
    #include "main.h"
    
    char szClassName[] ="WindowsApp";
    HINSTANCE hinst;
    HWND controls[10];
    HINSTANCE RichDLL;
    MyLVC list;
    listview.h
    Code:
    #ifndef H_LIST
    #define H_LIST
    #include "main.h"
    class MyLVC{
    	public:
    		MyLVC();
    		~MyLVC();
    		void Init(int xpos,int ypos,int xlen,int ylen,HWND owner,int lid,int style=0,int sx=0);
    		void SetDefaultColumnStyle(int mask,int fmt);
    		void AddColumn(char* name,int width,int mask=-1,int fmt=-1);
    	private:
    		int DefMask,DefFmt;
    		int colid;
    		HWND handle;
    };
    
    MyLVC::MyLVC(){
    	colid=DefMask=DefFmt=0;
    	return;
    }
    MyLVC::~MyLVC(){
    	return;
    }
    void MyLVC::SetDefaultColumnStyle(int mask, int fmt){
    	DefMask=mask;
    	DefFmt=fmt;
    	return;
    }
    void MyLVC::Init(int xpos,int ypos,int xlen,int ylen,HWND owner,int lid,int style,int sx){
    	handle=CreateWindowEx(0,WC_LISTVIEW,NULL,WS_CHILD|WS_VISIBLE|LVS_REPORT|sx,xpos,
    		ypos,xlen,ylen,owner,(HMENU)lid,GetModuleHandle(NULL),0);
    	SendMessage(handle,LVM_SETEXTENDEDLISTVIEWSTYLE,0,style);
    	return;
    }
    
    void MyLVC::AddColumn(char* name,int width,int mask,int fmt){
    	LVCOLUMN lvc={0};
    	if(mask<0){ lvc.mask=DefMask; }
    	else{ lvc.mask=mask; }
    	if(fmt<0){ lvc.fmt=DefFmt; }
    	else{ lvc.fmt=fmt; }
     	lvc.cx=width;
    	lvc.pszText=name;
    	SendMessage(handle,LVM_INSERTCOLUMN,colid,(LPARAM)&lvc);
    	colid++;
    	return;
    }
    #endif
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  8. #23
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    OK from compiler point of view - everything is OK
    Problems start on linker stage.

    You put function bodies in the listview.h
    so all functions present there are present in any c (and obj) file that includes this header.

    Leave only function prototypes in header file.
    Move all function bodies into the listview.cpp

    Leave only class definition in the header file
    Last edited by vart; 10-30-2006 at 06:15 AM.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #24
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Thanks.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Checking array for string
    By Ayreon in forum C Programming
    Replies: 87
    Last Post: 03-09-2009, 03:25 PM
  2. Confusion on header and source files
    By dnguyen1022 in forum C++ Programming
    Replies: 4
    Last Post: 01-17-2009, 03:42 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. more header files
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 10-28-2001, 01:56 PM