2015-07-27 2 views
2

посмотрите на следующий пример:C++ - Может ли следующий код вызвать неопределенное поведение?

#include <iostream> 
#include <string.h> 

void Func1(int x) 
{ 
    std::cout << "I'm function 1: " << x << std::endl; 
} 

void Func2(int x, const char* str) 
{ 
    std::cout << "I'm function 2: (this is arg1: " << x << " - args2: " << str << ")" << std::endl; 
} 

uintptr_t GetProcAddress(const char* _str) 
{ 
    if (strcmp(_str, "func1") == 0) 
    { 
     return reinterpret_cast<uintptr_t>(Func1); 
    } 
    else 
    { 
     return reinterpret_cast<uintptr_t>(Func2); 
    } 
} 

int main() 
{ 
    typedef void(*PROCADDR)(int, const char*); 
    PROCADDR ext_addr = nullptr; 
    ext_addr = (PROCADDR)GetProcAddress((const char*)"func1"); 

    //call the function 
    ext_addr(10, "arg"); 


    std::cin.get(); 
    return 0; 
} 

Мы в основном призывающую FUNC1 с 2 аргументами и может переключаться вызвать func2 с теми же аргументами, и все работает как задумано.

Конечно, адрес обоих аргументов всегда вставляется в стек, хотя вторая никогда не используется самой функцией.

Теперь я понимаю, что приведенный выше код никогда не должен использоваться в производственном коде, но мой главный вопрос заключается в том, может ли приведенный выше код вызывать UB или это код всегда должен действовать так?

С наилучшими пожеланиями хх

+1

Не является встроенной строкой уже 'const char *'? И что вы пытаетесь сделать здесь? Это кажется очень плохой идеей сверху донизу. Вызов функции, которая принимает два аргумента с одним аргументом *, может работать *, но это самый тривиальный случай, и я бы рассчитывал, что он работает в общем смысле. Оптимизация компилятора может легко избавиться от этого или, что еще хуже, не хочет касаться его, потому что они не могут предвидеть, что вы делаете. – tadman

+0

Точно покрывается [Вызов указателя функции, у которого назначенная функция имеет меньше аргументов, а затем тип указателя] (http://stackoverflow.com/questions/31479552/calling-a-function-pointer-whose-assigned-function-has -less -arguments-then-the-p) –

ответ

1

Да, это неопределенное поведение. From [expr.reinterpret.cast]:

Функциональный указатель может быть явно преобразован в указатель функции другого типа. Эффект вызова функции с помощью указателя на тип функции (8.3.5), который не совпадает с типом, используемым в определении функции, не определен.

+0

Спасибо, я, хотя это может быть UB, но ничего не нашел. –

+0

Существуют некоторые системы (например, Windows), где это приведет к сбою, поэтому это не является чисто теоретической проблемой. –

Смежные вопросы