如何在重载函数中使用#pragma startup?

时间:2013-10-03 17:19:08

标签: c++ startup pragma

假设我有两个重载函数:

fun1(int)
fun1()

在这种情况下,如何使用#pragma startup指令以fun1(int)启动程序的执行?

语法仅包含函数名称:

#pragma startup fun1 100

有什么方法可以在这两个函数之间做出选择?

更新

compiler- turbo c / c ++ 3.1(对于旧编译器而言很抱歉)

4 个答案:

答案 0 :(得分:3)

这是一个特定于Borland的指令,仍然是documented as well。它只允许您指定在输入main()函数之前运行的函数。您通常将它用于初始化函数。它是C和C ++实现所遭受的臭名昭着的“static initialization order fiasco”的小型创可贴。不太确定它会阻止流血,当程序变大时,不得不选择优先级数应该变得不切实际。

Anyhoo,你应该用什么作为main()的替代品。虽然我怀疑只要你不从函数返回并调用exit()就可以使它工作。你当然不能使用论证,CRT可以传递任何有意义的东西。因此,重载也无法正常工作。坚持使用main()。

答案 1 :(得分:2)

@ joey-rohan,我没有borland但是试图在下面提供一些代码来证明:

#pragma start需要非参数化函数,函数调用后的数字是函数的优先级,其中0表示最高,255表示最低。理想情况下(在某些编译器中有所不同)的函数应在#pragma调用之前定义。 Source: embarcadero

我已经做了一些侦察,并认为解决你的困境的方法是使用#define#pragma的混合来实现你想做的事情。例如:

#include <iostream>

#define myvalue 100
#define usemyvalue 0

void fun1(int passedInValue)
{
    // carry out function here
    std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
    std::cout << "in fun1(void)\n";
    std::cout << "Use my value = " << usemyvalue<< std::endl;
    if (usemyvalue==1)
    {
        std::cout << "Using fun1(int) with a value!\n";
        fun1((int)myvalue);  // remember to cast as an int here
    }
    else
    {
        //normal fun1()code here
        std::cout << "No var passed!\n";
        std::cout << "Running standard non parametrised code!\n";
    }

}

#pragma start fun1 10


int main()
{
   std::cout << "Hello World\n";

   return 0;
}

我知道这并不像我希望的那样优雅,因此它可能没有你想要的那么优雅,但它确实允许你需要的功能,只需要很少的修改。不幸的是,我只有GCC可以在这台机器上进行测试而且它似乎不支持#pragma start但它确实支持实现相同的不同方式(如C Language Constructors and Destructors with GCC所示) 所以这里有一些GCC的代码,我可以测试一下,让你看看如何实现你的要求(因为我讨厌一种无法证明的方法):

#include <iostream>

#define myvalue 100
#define usemyvalue 1   // this is the control switch to determine which to use, 
                       // if the value is 1 then will pass a variable, otherwise will use 
                       // the fun1(void) function
void fun1 (void) __attribute__((constructor));


void fun1(int passedInValue)
{
    // carry out function here
    std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
    std::cout << "in fun1(void)\n";
    std::cout << "Use my value = " << usemyvalue<< std::endl;
    if (usemyvalue==1)
    {
        std::cout << "Using fun1(int) with a value!\n";
        fun1((int)myvalue);  // remember to cast as an int here
    }
    else
    {
        //normal fun1()code here
        std::cout << "No var passed!\n";
        std::cout << "Running standard non parametrised code!\n";
    }

}

#pragma startup fun1

int main()
{
    std::cout << "now running main function.\n";
    std::cout << "Hello World\n"; 
    return 0;
}

我怀疑第二种方法也可以与Borlands编译器一起使用,但如果没有它,我就不能发誓。

希望这有帮助!

答案 2 :(得分:1)

我既没有找到关于编译器的任何文档,也没有使用编译器本身来检查我的猜测。但是从我记忆中来看,#pragma startup在没有参数的情况下获取函数并返回void。

如果你只留下int参数的函数,我会进一步猜测你的代码不会起作用。

无视这一点,我认为不可能将参数传递给以这种方式调用的函数。

作为一个解决方案,我建议你创建包装器函数,用必要的参数调用你想要的任何函数,例如:

void start()
{
#pragma startup start
    fun1( global_var_name );
}

答案 3 :(得分:1)

我不完全确定我理解这些限制,但是如何简单地定义另一个具有不同名称的函数以转发到您想要的函数?

void fun2() { fun1(42); }

#pragma startup fun2 100