Like Tree11Likes

Code::blocks 'undefined reference' error

This is a discussion on Code::blocks 'undefined reference' error within the General Discussions forums, part of the Community Boards category; I am using Code::Blocks 12.11 on Windows 8 I am following the tutorial here - Lesson 2 - Creating a ...

  1. #1
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323

    Code::blocks 'undefined reference' error

    I am using Code::Blocks 12.11 on Windows 8

    I am following the tutorial here - Lesson 2 - Creating a basic window - Natural Language Processing, London and I am receiving the error "undefined reference to 'MainWindow::m_hInstance'" in the MainWindow.cpp file. I don't know enough about the C++ language to guage whether there is an error in the code, or (more likely) it's an error in the Code::Blocks project set-up.

    I have three files: main.cpp, MainWindow.cpp, MainWindow.h

    main.cpp
    Code:
    #include <windows.h>
    #include "MainWindow.h"
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
    {
        MSG msg;
    
        MainWindow *winMain = new MainWindow(hInst);
        if(!winMain->Run(nCmdShow))
        {
            delete winMain;
            return 1; 
        }
    
        // Run the message loop. It will run until GetMessage() returns 0
        while (GetMessage (&msg, NULL, 0, 0))
        {
            // Translate virtual-key messages into character messages
            TranslateMessage(&msg);
            // Send message to WindowProcedure
            DispatchMessage(&msg);
        }
    
        delete winMain;
    
        return msg.wParam;
    }
    MainWindow.cpp
    Code:
    #include <windows.h>
    #include "MainWindow.h"
    
    char MainWindow::m_szClassName[] = "DrawLite";
    
    MainWindow::MainWindow(HINSTANCE hInstance)
    {
        m_hInstance = hInstance;
      
        m_wndClass.cbSize = sizeof(WNDCLASSEX);
        m_wndClass.style = CS_DBLCLKS;
        m_wndClass.lpfnWndProc = MainWndProc;
        m_wndClass.cbClsExtra = 0;
        m_wndClass.cbWndExtra = 0;
        m_wndClass.hInstance = hInstance;
        m_wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        m_wndClass.hCursor = LoadIcon(NULL, IDC_ARROW);
        m_wndClass.hbrBackground = (HBRUSH) COLOR_WINDOW;
        m_wndClass.lpszMenuName = NULL;
        m_wndClass.lpszClassName = m_szClassName;
        m_wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    
    LRESULT CALLBACK MainWindow::MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:
            return DefWindowProc (hwnd, msg, wParam, lParam);
        }
    
        return 0;
    }
    
    bool MainWindow::Run(int nCmdShow)
    {
        if(!RegisterClassEx(&m_wndClass))
            return false;
        m_hwnd = CreateWindowEx(
                     0,
                     m_szClassName,
                     "Draw Lite",
                     WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     500,
                     400,
                     NULL,
                     NULL,
                           m_hInstance,      
                     NULL
                 );
        if(!m_hwnd)
            return false;
        ShowWindow(m_hwnd, nCmdShow);
        return true;
    }
    MainWindow.h
    Code:
    #ifndef MAINWINDOW_H_INCLUDED
    #define MAINWINDOW_H_INCLUDED
    
    #include <windows.h>
    
    class MainWindow
    {
    
    public:
        MainWindow(HINSTANCE hInstance);
        ~MainWindow();
    
        static LRESULT CALLBACK MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
        bool Run(int nCmdShow);
    
    private:
        WNDCLASSEX m_wndClass;
        static HINSTANCE m_hInstance;
        HWND m_hwnd;
        static char m_szClassName[];
    
    };
    
    #endif // MAINWINDOW_H_INCLUDED
    I have searched Google for undefined reference problems and have found a few posts which were solved by adding the files to the project - I have added the files by right clicking the project and choosing "add files" and making sure all the boxes are ticked.

    I have also tried to add the project directry to the linker tab as described in the Codeblocks manual, and then tried to add the object file in the same way.

    I have got the feeling that it is an error in the project set-up, but I'm out of ideas.
    Fact - Beethoven wrote his first symphony in C

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,451
    > I have three files: main.cpp, MainWindow.cpp, MainWindow.h
    I believe that all you should need is in project->settings->source files, you just have the two .cpp files listed.

    So when you do a full build, you should see two compile lines (for each of the .cpp files), then the linker producing the executable.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323
    There doesn't seem to be a "settings" under the project menu (at least with the version 12.11 that I am running) - However, there is a "Properties" option and the tab "Build Targets". All three files are in the "Build Target Files" and all are selected.

    It looks like the two files have been included in the compiler input - Here is the output from the 'Build Log'

    Code:
    
    -------------- Build: Debug in Win32Tuturial (compiler: GNU GCC Compiler)---------------
    
    
    mingw32-g++.exe  -o bin\Debug\Win32Tuturial.exe obj\Debug\main.o obj\Debug\MainWindow.o    
    
    obj\Debug\MainWindow.o: In function `ZN10MainWindowC2EP11HINSTANCE__':
    
    D:/Programming/Win32Tuturial/MainWindow.cpp:8: undefined reference to `MainWindow::m_hInstance'
    
    obj\Debug\MainWindow.o: In function `ZN10MainWindow3RunEi':
    
    D:/Programming/Win32Tuturial/MainWindow.cpp:61: undefined reference to `MainWindow::m_hInstance'
    
    collect2.exe: error: ld returned 1 exit status
    
    Process terminated with status 1 (0 minutes, 0 seconds)
    
    2 errors, 0 warnings (0 minutes, 0 seconds)
    Fact - Beethoven wrote his first symphony in C

  4. #4
    ZuK
    ZuK is offline
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    You need to define m_hInstance the same way as you did with m_szClassName[]
    try
    Code:
    char MainWindow::m_szClassName[] = "DrawLite";
    HINSTANCE MainWindow::m_hInstance;  // add this line
    in MainWindow.cpp
    Kurt

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323
    That seemed to work, thanks ZuK.

    What is the reason why this needs to be done?

    As I said, I don't know enough about C++ to judge if there was an error in the code.
    Fact - Beethoven wrote his first symphony in C

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,439
    Because it's static - there is only one instance of the variable in the program.
    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.

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323
    Thanks Elysia

    So just to clarify:

    A Static variable in a class is implemented as one variable which is availible to all classes
    i.e. winMain1.m_hInstance and winMain2.m_hInstance are the same variable (same memory location)

    A Static variable in a class must be declared in the same way a function is declared for a class. However, a non-static variable does not need to be declared in this way.
    Fact - Beethoven wrote his first symphony in C

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,436
    Quote Originally Posted by Click_here
    A Static variable in a class must be declared in the same way a function is declared for a class.
    Not quite: a non-const static member variable that is declared in a class definition must be defined outside of the class definition, in exactly one translation unit. The same applies to const static member variables, with the exception that such variables of integer type can be defined in the class definition by initialising them to a constant there.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323
    What do you mean by "translation unit", laserlight?

    This is my current understanding:
    A function can be fully defined in a class definition or external to that class definition. However, a static variable needs to be declared like a global variable, unless it is a constant integer where an exception to the rule is made on the event that a definition was imediately made.

    Code:
    class apple
    {
      /* No further defining is needed here: */
      int banana;
      const static int grape = 4;
      apple();
      ~apple();
    
      /* These need to be defined again globally */
      const static int pear;
      static char pineapple[42];
      
    };
    Fact - Beethoven wrote his first symphony in C

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,436
    Quote Originally Posted by Click_here
    What do you mean by "translation unit", laserlight?
    A source file with the headers included.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,207
    Quote Originally Posted by Click_here View Post
    What do you mean by "translation unit", laserlight?
    A translation unit is a single source file (e.g. with a .cpp extension) and the collection of files it #include's. All laserlight is saying is that, if your project contains more than one source file, a non-const static member of the class is only allowed to be defined in one of them.

    Quote Originally Posted by Click_here View Post
    This is my current understanding:
    A function can be fully defined in a class definition or external to that class definition. However, a static variable needs to be declared like a global variable, unless it is a constant integer where an exception to the rule is made on the event that a definition was imediately made.
    Not quite. To reiterate what laserlight said, a static member of a class needs to be DEFINED outside the class, in exactly one translation unit.

    A variable declaration simply tells the compiler to assume that a variable with that name and type exists, so subsequent code in that translation unit can do things to that variable (retrieve its value, change the value, etc). A definition actually causes the variable to exist. Where you are possibly getting confused is that a definition is a particular type of declaration.

    A global variable may be declared in multiple translation units (eg by placing the declaration within a header file which is #include'd in multiple translation units). It must be defined in exactly one of them.
    Right 98% of the time, and don't care about the other 3%.

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,439
    You should, if possible, use std::string for all your strings, not char arrays.
    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.

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    29
    try adding
    Code:
     int main()
    {
    
    }
    at the end of program.

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,439
    main is not used in Windows programs.
    Now that I think about it, why are you using operator new here? It seems superfluous. You should probably remove 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
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,323
    Quote Originally Posted by Elysia
    You should, if possible, use std::string for all your strings, not char arrays.
    This tutorial uses some C string functions later on (wsprintf in particular). I might go back through the tutorial's code later and try to learn and implement some of the C++'s string functionality.

    Quote Originally Posted by Elysia
    Now that I think about it, why are you using operator new here? It seems superfluous. You should probably remove it.
    I am following a tutorial which has chosen to dynamically allocate the class - In fact the WinMain function was so simple, I just copied and pasted from the tutorial without a second thought. I'm not going to change it for changes sake.

    Quote Originally Posted by Aeoskype
    try adding
    Code:
    int main()
    {
     
    }
    at the end of program.
    When programming a graphical windows based application, the entry point WinMain instead of main - Adding "main" after the WinMain is already in the code would be a bad choice.

    Here it is on the MSDN website - WinMain entry point (Windows)

    I think that the tutorial I have been following skims over quite a lot, but through using Google, I'm finding it quite good. However, these tutorials, as well as the MSDN site, have been heavily critisized for not using modern C++ and using C string functions (which is fine for me, because I know C very well, but not C++).
    Fact - Beethoven wrote his first symphony in C

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 17
    Last Post: 07-08-2011, 07:11 AM
  2. Can't Compile a code!!! I ran into "undefined reference to" error.
    By andereasmehdi in forum Linux Programming
    Replies: 19
    Last Post: 06-28-2011, 05:45 AM
  3. gcc error, undefined reference
    By drshmoo in forum C Programming
    Replies: 2
    Last Post: 04-04-2011, 09:33 PM
  4. Undefined reference error
    By pshirishreddy in forum C Programming
    Replies: 11
    Last Post: 08-02-2009, 06:34 PM
  5. undefined reference error
    By gcctest in forum C Programming
    Replies: 3
    Last Post: 12-19-2008, 07:17 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21