4

I would like to make a function that can print the contents of another function without breaking the functionality of the copied function.

For example:

int functionToCopy()
{
    int a{ 5 };
    int b{ 6 };
    
    return a + b;
}

void printCopiedFunction()
{
    some magical code to print the contents of the first function;
}

int main()
{
    std::cout << functionToCopy() << '\n';
    std::cout << printCopiedFunction() << '\n';

    return 0;
}

Output:

11

int functionToCopy()
{
    int a{ 5 };
    int b{ 6 };
    
    return a + b;
}

I'm only a beginner and C++ is my first language. I've done a lot searching and thinking but the only way I could think of is just literally copying the function and making a 2nd function a string, which would double my code and I'd rather avoid that. The program I'd like to do this with currently has 26 functions that would need copying like that so a single function that can be reused would be much preferred.

std::string copiedFunction()
{
    std::string str{ R"(
    int functionToCopy()
    {
    int a { 5 };
    inb b { 6 };

    return a + b;
    })"
    };
return str;
}

Any help is much appreciated! This is the only time I've ever asked for help like this on a forum but I think this is just beyond my abilities at this point. I understand this may not be possible or it may be very complex and just beyond my scope at this time. Thank you in advance!

Z With Glasses
  • 106
  • 1
  • 7
  • 2
    That's called `reflection`. But I am not knowledgeable enough to provide an answer. You could just have your program read it's own source files but that's weak. – Vorac Jun 19 '21 at 08:07
  • 2
    You could use text parsing and macros. To print a function, get its name from `__FUNCTION__`, get file name from `__FILE__`. Read the file and print the function. But you would have to call print from the function itself. – Aditya Singh Rathore Jun 19 '21 at 10:05

1 Answers1

4

C++ does not have reflection so you can't directly do this using the language alone. But you can do it by moving the function to a header file, #includeing that file in your .cpp file, and also building the header file into an object file which makes it contents available as a constant string.

First, put this in foo.h:

inline int functionToCopy()
{
    int a{ 5 };
    int b{ 6 };

    return a + b;
}

Then, using the information from https://stackoverflow.com/a/46221837/4323 use objcopy to create an object file:

objcopy --input binary --output elf64-x86-64 foo.h foo.o

Then change your main file like this:

#include <iostream>
#include <string_view>
#include "foo.h"

extern "C" const char* _binary_foo_h_start; // defined in foo.o
extern "C" const char* _binary_foo_h_size;

std::string_view printCopiedFunction()
{
    return {_binary_foo_h_start, _binary_foo_h_size};
}

int main()
{
    std::cout << functionToCopy() << '\n';
    std::cout << printCopiedFunction() << '\n';
}

And link foo.o into your executable at build time.

Note that objcopy is available on Linux and some other systems, you may need to look for an equivalent on your platform. For example if you have xxd: https://stackoverflow.com/a/411000/4323

On Windows you can embed the text file (which is the header file) as a "resource" in your executable, and load the resource at runtime, like this: Embed Text File in a Resource in a native Windows Application

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Would this be the right thing to use for Windows and MSVC? https://learn.microsoft.com/en-us/cpp/build/reference/extracting-a-library-member?view=msvc-160 I've been trying to get it to work by using that to create an .obj file but I just can't figure it out. I'm wondering if I'm going about it the wrong way or trying to use LIB in a way that's not possible. I'm not sure what the replacement for binary_foo_h_start and binary_foo_h_size would be. It also seemed to me as though I'd need a .cpp static library to make an .obj with LIB instead of an .h – Z With Glasses Jun 20 '21 at 14:23
  • So I've decided to give up on this for now. I think it's just beyond my knowledge at the moment. I managed to create an .obj and learned a lot along the way but I can't figure out how to get anything from the .obj file. I can't find anything for windows equivalent to the _start _size of objcopy. I appreciate your help and hopefully I'll come back to this eventually with some working code for other folks. If someone is wanting to do this for windows I'd suggest taking a look at https://www.cygwin.com/ – Z With Glasses Jun 21 '21 at 06:42
  • @ZWithGlasses That LIB comment you tried is not going to work for this, it only copies binary code to binary code, not text to binary like we want for this purpose. I've edited my answer to add a link for how to embed a text file in a Windows executable, please see the last paragraph. – John Zwinck Jun 21 '21 at 09:40