Tool sprawdzający co robi kod.

0

Cześć,
Szukam jakiegoś tool'a który sprawdzi czy dwa kawałki kodu żródłowego w języku C wykonują to samo. Czy istnieje coś takiego?
Przykładowo te dwie funkcje wykonują to samo zadanie, mimo tego że są napisane inaczej.

void fun1(uint8_t a)
{
    if(a == 0)
    {
        doSth1();
    }
    else if(a == 1)
    {
        doSth2();
    }
    else
    {
        doSth3();
    }
}

void fun2(uint8_t a)
{
    switch(a)
    {
        case 0:
            doSth1();
        break;
        
        case 1:
            doSth2();
        break;
        
        default:
            doSth3();
        break;
    }
}
1

Nie sądzę, żeby istniało coś takiego.

  1. Nawet zakładając, że te funkcje są pure udowodnienie ich równoważności to zadanie stricte matematyczne
  2. Nadal zakładając, że są pure de facto można być sprawdzić efekty działania dla każdej wartości wejściowej (szczególnie że to 1 bajtowy int)
  3. Niestety, te funkcje mogą robić magiczne rzeczy w środku, w zasadzie żeby wiedzieć czy robią to samo trzeba by porównywać stany pamięci przed i po wykonaniu (bo programy to funkcje z pamięci w pamięć). W ogólnym przypadku łatwiej wydedukować czy robią to samo je czytając.

Edit:
Ten przykład w poście jest zbyt trywialny, żeby stanowił przykład dla tego problemu

2

To mi troche przypomina pytanie o testy :D Tzn zazwyczaj piszesz kod i testy, potem ten kod refaktoryzujesz a testy powinny wykazać czy nowy kod robi to samo co stary no ale w tym przypadku wiesz co ma robić a czegoś takiego jak nie wiem co robi ale porównajmy wyniki to to raczej nie ma i nie tędy droga. Powiedz raczej do czego ci to potrzebne.

0

Właśnie robię refraktoryzację dość dużego modułu. Testy nie zostały jeszcze napisane. Kod jest niskopoziomowy i obecnie nie mam dostępu do HW aby to sprawdzić w rzeczywistości, dlatego pomyślałem o jakimś narzędziu sprawdzającym.

1
Saalin napisał(a):
  1. Nawet zakładając, że te funkcje są pure udowodnienie ich równoważności to zadanie stricte matematyczne

Jest gorzej. To zadanie już zostało rozwiązane.

3

Załóżmy, że jeden program wpada w nieskończoną pętlę i nigdy się nie kończy.
Sprawdzenie czy drugi „robi to samo” sprowadza się więc do próby udowodnienia, że ten drugi też się nigdy nie kończy.

https://pl.wikipedia.org/wiki/Problem_stopu

Przykro mi.

0

Możesz sprawdzić, czy kompilatory generują dla nich identyczny kod w assembly (np. na godbolt.org). Przy czym jedyne, co tak udowodnisz, to że funkcje mają jednakowe działanie. Różny kod wynikowy nic nie mówi.

0

W C może być problem, wiem że w przypadku języków generujących kod pośredni są narzędzia do automatycznego wygenerowania testów Java -> Randoop, C# -> IntelliTest. Bawiłem się kiedyś tym jednak są one kiepskie w przypadku dużych modułów, w skrócie do niczego większego niż prosty kalkulator nie udało mi się wygenerować :D :D :D wymagało to ręcznego podefiniowania mock'ów niektórych klas co już jest słabe i w sumie nic nie automatyzuje albo po prostu rzucało że nie umie wygenerować kodu uruchamijącego jakiś inny bo nie.
Poza tym dało się tak napisać metode/funkcje nawet prostą żeby testy jednak w 100% nie testowały jej (wykorzystują Dynamic Symbolic Execution) więc przy generowaniu testu było pilnowane żeby osiągnąć wszystkie ścieżki w kodzie więc jak był gdzieś powiedzmy if(x == 0 || x == 1) to jak wygenerowało test pokrywający ścieżke z parameter x = 0 to już nie generowało dla x = 1 nawet nie szukało że można tylko odhaczało ścieżke w kodzie jak przetestowaną.
Wiem że to nie dokładnie to co szukasz ale problem podobny, który nie ma dobrego rozwiązania na ten moment więc myślę ze nie ma takiego narzędzia którego szukasz (chcę się mylić i chętnie o jakimś przeczytam jeśli znacie). Powodzenia ;)

1

Można spróbować użyć testów mutacyjnych do tego. Ale nie używałem, więc to tylko luźny pomysł.
https://github.com/mull-project/mull
https://github.com/nlohmann/mutate_cpp

1 użytkowników online, w tym zalogowanych: 0, gości: 1