anthwlock / untrunc

Restore a truncated mp4/mov. Improved version of ponchio/untrunc
GNU General Public License v2.0
1.87k stars 182 forks source link

Compilation fails on 32-bit systems due to incorrect implicit type casting of arguments to min() #71

Closed jlick closed 3 years ago

jlick commented 3 years ago

On a 64-bit Debian 10 buster system the following compilation method works without issue:

sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev
git clone https://github.com/anthwlock/untrunc
cd untrunc
make

However, on a substantially similar 32-bit Debian buster system, the same compilation method fails with the following errors:

% make
untrunc: 1b1127d
ffmpeg: shared

g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/track.o -c src/track.cpp
g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/codec.o -c src/codec.cpp
g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/atom.o -c src/atom.cpp
g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/common.o -c src/common.cpp
g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/mutual_pattern.o -c src/mutual_pattern.cpp
g++ -MMD -MP -DUNTR_VERSION=\"1b1127d\" -std=c++11 -D_FILE_OFFSET_BITS=64 -g -o .build_shared/src/mp4.o -c src/mp4.cpp
src/mp4.cpp: In member function ‘void Mp4::chkUntrunc(FrameInfo&, Codec&, int)’:
src/mp4.cpp:548:58: error: no matching function for call to ‘min(long int, int64_t)’
  auto sz = min(8L, current_mdat_->contentSize() - end_off);
                                                          ^
In file included from /usr/include/c++/8/bits/char_traits.h:39,
                 from /usr/include/c++/8/string:40,
                 from src/mp4.cpp:22:
/usr/include/c++/8/bits/stl_algobase.h:195:5: note: candidate: ‘template<class _Tp> const _Tp& std::min(const _Tp&, const _Tp&)’
     min(const _Tp& __a, const _Tp& __b)
     ^~~
/usr/include/c++/8/bits/stl_algobase.h:195:5: note:   template argument deduction/substitution failed:
src/mp4.cpp:548:58: note:   deduced conflicting types for parameter ‘const _Tp’ (‘long int’ and ‘int64_t’ {aka ‘long long int’})
  auto sz = min(8L, current_mdat_->contentSize() - end_off);
                                                          ^
In file included from /usr/include/c++/8/bits/char_traits.h:39,
                 from /usr/include/c++/8/string:40,
                 from src/mp4.cpp:22:
/usr/include/c++/8/bits/stl_algobase.h:243:5: note: candidate: ‘template<class _Tp, class _Compare> const _Tp& std::min(const _Tp&, const _Tp&, _Compare)’
     min(const _Tp& __a, const _Tp& __b, _Compare __comp)
     ^~~
/usr/include/c++/8/bits/stl_algobase.h:243:5: note:   template argument deduction/substitution failed:
src/mp4.cpp:548:58: note:   deduced conflicting types for parameter ‘const _Tp’ (‘long int’ and ‘int64_t’ {aka ‘long long int’})
  auto sz = min(8L, current_mdat_->contentSize() - end_off);
                                                          ^
In file included from /usr/include/c++/8/algorithm:62,
                 from src/mp4.cpp:25:
/usr/include/c++/8/bits/stl_algo.h:3450:5: note: candidate: ‘template<class _Tp> _Tp std::min(std::initializer_list<_Tp>)’
     min(initializer_list<_Tp> __l)
     ^~~
/usr/include/c++/8/bits/stl_algo.h:3450:5: note:   template argument deduction/substitution failed:
src/mp4.cpp:548:58: note:   mismatched types ‘std::initializer_list<_Tp>’ and ‘long int’
  auto sz = min(8L, current_mdat_->contentSize() - end_off);
                                                          ^
In file included from /usr/include/c++/8/algorithm:62,
                 from src/mp4.cpp:25:
/usr/include/c++/8/bits/stl_algo.h:3456:5: note: candidate: ‘template<class _Tp, class _Compare> _Tp std::min(std::initializer_list<_Tp>, _Compare)’
     min(initializer_list<_Tp> __l, _Compare __comp)
     ^~~
/usr/include/c++/8/bits/stl_algo.h:3456:5: note:   template argument deduction/substitution failed:
src/mp4.cpp:548:58: note:   mismatched types ‘std::initializer_list<_Tp>’ and ‘long int’
  auto sz = min(8L, current_mdat_->contentSize() - end_off);
                                                          ^
make: *** [Makefile:137: .build_shared/src/mp4.o] Error 1

These errors are due to the compiler implicitly assuming the type of the first argument of this call to min to be 32-bit on 32-bit systems and 64-bit on 64-bit systems, while the second argument is always a 64-bit value. This creates a type incompatibility which the compiler rejects.

This can be fixed by changing this line to the following to force the first argument to be 64-bit:

auto sz = min(static_cast<int64_t>(8), current_mdat_->contentSize() - end_off);

After this change, make finishes without error and the resulting binary appears to work correctly.

anthwlock commented 3 years ago

Thank you. I find it odd that following is not valid: min(8LL, some_int64_var); Apparently int64_t becomes long on 64bit systems, and thus it becomes min(long long, long)..

jlick commented 3 years ago

Even worse it also depends on OS and compiler how big long and long long are on 32-bit and 64-bit systems. Anyhow, thanks for the quick fix.

jlick commented 3 years ago

d6f0790 successfully compiles on:

Debian buster 32-bit Debian buster 64-bit Raspbian buster 32-bit