CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jul 2017
    Location
    Greece
    Posts
    130

    Question [vsCode and gdb]: Breakpoints don't work with macros?

    Hello!

    I made a unit testing framework and for the first time, I noticed that breakpoints won't work with macros. This is how my tests look like:


    main.cpp
    Code:
    #include <VampTest/VampTest.h>
    #include <VampStructures/VampStructures.h>
    
    
    bool compare(int current, int searching)
    {
        return current == searching;
    }
    
    VMPT_INIT
    (
        VMPT_TEST
        (
            linked_list, creation,
            {   
    
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
                //The size of the list must be 10 by now.
                VMPT_NOTEQUAL(10, list.getSize())
    
                //Counter.
                int i;
    
                //Check the values.
                for (i = 0; i < list.getSize(); i++)
                    if (list.hasNext())
                        VMPT_NOTEQUAL(i, list.getNext())
    
                //I must be 10 by now.
                VMPT_NOTEQUAL(10, i);
    
                //list.hasNext() must return false at this point.
                VMPT_NOTEQUAL(false, list.hasNext());
            }
        )
    
    
        VMPT_TEST
        (
            linked_list, has_next_overflow,
            {
    
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
                //Check more that the size of the list.
                //If .hasNext() works correctly, the text should succeed.
                for (int i = 0; i < list.getSize()+20; i++)
                    if (list.hasNext())
                        VMPT_NOTEQUAL(i, list.getNext())
            }
        )
    
        
        VMPT_TEST
        (
            linked_list, has_next_reset,
            {
    
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
                //Check more that the size of the list.
                for (int i = 0; i < list.getSize(); i++)
                    if (list.hasNext())
                        VMPT_NOTEQUAL(i, list.getNext())
    
                //Reset the list.
                list.reset();
    
                //has next must be true here.
                VMPT_NOTEQUAL(true, list.hasNext());
    
                //Counter.
                int i;
    
                //Check more that the size of the list.
                for (i = 0; i < list.getSize(); i++)
                    if (list.hasNext())
                        VMPT_NOTEQUAL(i, list.getNext())
                
                //I must be 10 by now.
                VMPT_NOTEQUAL(10, i);
    
                //list.hasNext() must return false at this point.
                VMPT_NOTEQUAL(false, list.hasNext());
            }
        )
    
    
    
        VMPT_TEST
        (
            linked_list, empty,
            {
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //List must not have next when its empty.
                VMPT_EQUAL(true, list.hasNext())
                
                //Size must be zero.
                VMPT_NOTEQUAL(0, list.getSize())
            }
        )
    
        
        VMPT_TEST
        (
            linked_list, search,
            {
    
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
    
                //Search for number 5
                void *n  = list.search(compare, 5);
                
                //5 MUST exist in the list.
                VMPT_EQUAL(true, (n == list.end()) )
    
                //list.get() should return 5.
                VMPT_NOTEQUAL(5, list.get(n))
    
                //Search for number 11
                n  = list.search(compare, 11);
                
                //11 MUST not exist in the list.
                VMPT_NOTEQUAL(true, (n == list.end()) )
            }
        )
    
        
        VMPT_TEST
        (
            linked_list, clear,
            {
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
                //Clear the list.
                list.clear();
    
                //The list must be empty by now.
                VMPT_NOTEQUAL(0, list.getSize())
    
                //List must not have next when its empty.
                VMPT_EQUAL(true, list.hasNext())
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
    
                //Counter.
                int i = 0;
    
                //Get the items.
                while (list.hasNext())
                {
                    VMPT_NOTEQUAL(i, list.getNext())
                    i++;
                }
    
                //Size must be ten by now.
                VMPT_NOTEQUAL(10, list.getSize())
                
                //I must be 10 by now.
                VMPT_NOTEQUAL(10, i);
    
                //list.hasNext() must return false at this point.
                VMPT_NOTEQUAL(false, list.hasNext());
            }
        )
    
    
    
    
        VMPT_TEST
        (
            linked_list, remove_item,
            {
                //Create the list.
                VMPS::LinkedList<int> list;
    
                //Fill it with 10 values.
                for (int i = 0; i < 10; i++)
                    list.append(i);
                
                //find number 5.
                void *s = list.search(compare, 5);
    
                //Remove the node which holds number 5.
                int num = list.remove(s);
    
                //Remove must return 5.
                VMPT_NOTEQUAL(5, num);
    
                //The size must be 9.
                VMPT_NOTEQUAL(9, list.getSize());
    
                //Remove all the remaining values.
                int i = 0;
                while (list.getSize() > 0)
                {
                    s   = list.search(compare, i);
    
                    if (i == 5)
                        VMPT_NOTEQUAL( true, (s==list.end()) )
                    
                    else
                    {
                        num = list.remove(s);
                        VMPT_NOTEQUAL(i, num);
                    }
    
                    i++;
                }
    
                //The size must be 0.
                VMPT_NOTEQUAL(0, list.getSize());
                
                //Has next must be false.
                VMPT_NOTEQUAL(false, list.hasNext());
            }
        )
        
    )
    The problem is that if I add a break point somewhere in main.cpp the breakpoint won't stop the debugger at that point. If I add a breakpoint inside the implementation of the code which I'm testing the break point works.

    I am exporting debugging symbols in the compilation.

    Is this an expected behavior and why? How can I debug this code then?

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [vsCode and gdb]: Breakpoints don't work with macros?

    If you're using function-like macros, then this isn't recommended for c++. Note that macros are processed by the pre-processor and not by the actual c++ compiler. By the time the c++ compiler gets the code, all the macro expansions have been performed by the pre-processor. So the debug symbols etc etc know nothing about any macros used.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Jul 2017
    Location
    Greece
    Posts
    130

    Re: [vsCode and gdb]: Breakpoints don't work with macros?

    I understand now. Well, I'm trying to figure another implementation which googletest follows and I think it will work.

    Code:
    #include <iostream>
    #include <ctime>
    #include <vector>
    
    
    #define TEST(case_name, test_name)\
        int case_name##_##test_name();\
        Fake case_name##_##test_name##_( case_name##_##test_name );\
        int case_name##_##test_name()
    
    
    typedef int (*func)();
    
    std::vector<func> funcs;
    
    class Fake
    {
        public:
        Fake(func f)
        {
            funcs.push_back(f);
        }
    };
    
    
    TEST(case1, test1)
    {
        std::cout << "hello world" << std::endl;
        return 0;
    }
    
    
    TEST(case1, test2)
    {
        std::cout << "hello test2" << std::endl;
        return 0;
    }
    
    int main()
    {
        for (func f : funcs)
            f();
            
        return 0;
    }
    As you can see, I'm trying to split the macro with the actuall body of the function. The problem is that in order to register the function pointer of the test I have to somehow call some code in the outer scope. I'm doint this using a Fake global initialised object which push through it's construtor that test func pointer.

    If I declare 10000 tests I need 10000 global different Fake objects.

    This work, but what is the limit? Is there a limit by the operating system on how many glabal objects I can define?
    Last edited by babaliaris; September 8th, 2019 at 06:39 AM.

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: [vsCode and gdb]: Breakpoints don't work with macros?

    Any reason not to check out existing unit test frameworks without rolling your own?

  5. #5
    Join Date
    Jul 2017
    Location
    Greece
    Posts
    130

    Re: [vsCode and gdb]: Breakpoints don't work with macros?

    Quote Originally Posted by Arjay View Post
    Any reason not to check out existing unit test frameworks without rolling your own?
    I'm already using others, like google test. Just for fun and knowledge I'm creating my own. Google test also uses global variables to achieve that.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: [vsCode and gdb]: Breakpoints don't work with macros?

    Quote Originally Posted by babaliaris View Post
    I'm already using others, like google test. Just for fun and knowledge I'm creating my own. Google test also uses global variables to achieve that.
    For fun try emulating modern test framework features like dependency injection and inversion of control rather than the old style macros.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured