2

假设我有两个重载函数:

fun1(int)
fun1()

在这种情况下,我如何使用#pragma startup指令来开始我的程序的执行fun1(int)

语法仅包含函数名称:

#pragma startup fun1 100

有什么方法可以让我在这两个功能之间做出选择?

更新:

编译器 - turbo c/c++ 3.1(对不起,旧的编译器)

4

4 回答 4

3

这是一个 Borland 特定的指令,仍然有文档记录。它只是让您指定一个在进入 main() 函数之前运行的函数。您通常将其用于初始化功能。对于C 和 C++ 实现所遭受的臭名昭著的“静态初始化顺序惨败”,这是一个小小的创可贴。不太确定它是否会止血,当程序变大时,必须选择优先级编号应该变得不切实际。

不管怎样,你不应该用任何东西来代替 main()。尽管我怀疑只要您不从函数返回并调用exit(),您就可以使其工作。当然,您不能使用参数,CRT 可以传递的没有任何意义。所以重载也不能工作。坚持使用 main()。

于 2013-10-08T20:16:58.010 回答
2

@joey-rohan,我没有 borland,但尝试在下面提供一些代码来演示:

#pragma start需要一个非参数化函数,函数调用之后的数字是函数的优先级,其中 0 是最高的,255 是最低的。理想情况下,该函数(在某些编译器中有所不同)应在#pragma调用之前定义。 资料来源: 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 语言构造函数和 GCC 析构函数所示, 所以这里是 GCC 的一些代码,我可以进行测试以让您了解如何实现您的要求(因为我讨厌 pst 一种无法证明的方法):

#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 编译器,但如果无法访问它,我不能发誓。

希望这可以帮助!

于 2013-10-15T10:33:42.883 回答
1

我既找不到关于您的编译器的任何文档,也无法使用编译器本身来检查我的猜测。但据我记得,#pragma startup接受没有参数的函数并返回 void。

我会进一步猜测,如果您只留下带int参数的函数,您的代码将无法正常工作。

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

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

void start()
{
#pragma startup start
    fun1( global_var_name );
}
于 2013-10-08T18:35:27.813 回答
1

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

void fun2() { fun1(42); }

#pragma startup fun2 100
于 2013-10-14T22:01:05.523 回答