google / googletest

GoogleTest - Google Testing and Mocking Framework
https://google.github.io/googletest/
BSD 3-Clause "New" or "Revised" License
34.47k stars 10.08k forks source link

compile time error (MSVC, in combination with <random>) #3311

Open lnw opened 3 years ago

lnw commented 3 years ago

Since March 10th, likely since bcfcf75, we are getting a compile time error with a trivial program that includes gtest/gtest.h and \<random>, on windows, using MSVC (tested with two versions, eg 14.28.29910).

For example: randomnumberstest.cpp: ---<<---

include "gtest/gtest.h"

include "randomnumbers.h"

--->>--

randomnumbers.h: ---<<---

pragma once

include \<random>

extern std::subtract_with_carry_engine<unsigned, 24, 10, 24> laggedFib; void inline seedLaggedFib(int seed) { laggedFib.seed(seed); } --->>---

Leading to the below errors/warnings. This hasn't been a problem previously. Given that this is a system I cannot remotely log into, this is all I can say at this point. If this does not hint at anything, I can try to narrow it down further in the next days.

1>randomnumberstest.cpp 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\include\random(497,92): error C2064: term does not evaluate to a function taking 0 arguments 1>C:\proj\imgrec\build\googletest-src\googletest\include\gtest/gtest-printers.h(220): message : see reference to function template instantiation 'std::linear_congruential<unsigned int,40014,0,2147483563>::linear_congruential<const type_info,0>(_Gen &)' being compiled 1> with 1> [ 1> _Gen=const type_info 1> ] 1>C:\proj\imgrec\build\googletest-src\googletest\include\gtest/gtest-printers.h(220): message : see reference to function template instantiation 'std::linear_congruential<unsigned int,40014,0,2147483563>::linear_congruential<const type_info,0>(_Gen &)' being compiled 1> with 1> [ 1> _Gen=const type_info 1> ] 1>C:\proj\imgrec\build\googletest-src\googletest\include\gtest/gtest-printers.h(317): message : see reference to function template instantiation 'void testing::internal::internal_stream_operator_without_lexical_name_lookup::StreamPrinter::PrintValue<type_info,void,std::basic_ostream<char,std::char_traits>&>(const T &,std::ostream )' being compiled 1> with 1> [ 1> T=type_info 1> ] 1>C:\proj\imgrec\build\googletest-src\googletest\include\gtest/gtest-printers.h(446): message : see reference to function template instantiation 'void testing::internal::PrintWithFallback(const T &,std::ostream )' being compiled 1> with 1> [ 1> T=type_info 1> ] 1>C:\proj\imgrec\build\googletest-src\googletest\include\gtest/gtest-printers.h(660): message : see reference to function template instantiation 'void testing::internal::PrintTo(const T &,std::ostream *)' being compiled 1> with 1> [ 1> T=type_info 1> ] 1>Done building project "CommonTests.vcxproj" -- FAILED.

the-code-cult commented 3 years ago

Can googletest be compiled with -werror enabled at all? I see that, it really diverse in nature supporting so many compilers on variety of OS.

I am facing lot of issue with enabling -wundef and -werror combinations.

yhmtsai commented 2 years ago

Is there any update or workaround for this issue? When the test body contains random generator like ranlux48 and the test has the object which can not be printed directly, it will lead this issue. Removing the random generator or the test can pass compilation. The error message

C:\BuildTools\VC\Tools\MSVC\14.29.30037\include\random(486,92): error C2064: term does not evaluate to a function takin
g 0 arguments [C:\ginkgo\build\reference\test\matrix\reference_test_matrix_dense_kernels.vcxproj]
C:\ginkgo\build\_deps\googletest-src\googletest\include\gtest/gtest-printers.h(213): message : see reference to functio
n template instantiation 'std::linear_congruential<unsigned __int64,40014,0,2147483563>::linear_congruential<const T,0>
(_Gen &)' being compiled [C:\ginkgo\build\reference\test\matrix\reference_test_matrix_dense_kernels.vcxproj]
          with
          [
              T=const gko::Executor,
              _Gen=const gko::Executor
          ]
C:\ginkgo\build\_deps\googletest-src\googletest\include\gtest/gtest-printers.h(213): message : see reference to functio
n template instantiation 'std::linear_congruential<unsigned __int64,40014,0,2147483563>::linear_congruential<const T,0>
(_Gen &)' being compiled [C:\ginkgo\build\reference\test\matrix\reference_test_matrix_dense_kernels.vcxproj]
          with
          [
              T=const gko::Executor,
              _Gen=const gko::Executor
          ]
C:\ginkgo\build\_deps\googletest-src\googletest\include\gtest/gtest-printers.h(310): message : see reference to functio
n template instantiation 'void testing::internal::internal_stream_operator_without_lexical_name_lookup::StreamPrinter::
PrintValue<T,void,std::basic_ostream<char,std::char_traits<char>>&>(const T &,std::ostream *)' being compiled [C:\ginkg
o\build\reference\test\matrix\reference_test_matrix_dense_kernels.vcxproj]
          with
          [
              T=const gko::Executor
          ]
C:\ginkgo\build\_deps\googletest-src\googletest\include\gtest/gtest-printers.h(439): message : see reference to functio
n template instantiation 'void testing::internal::PrintWithFallback<T>(const T &,std::ostream *)' being compiled [C:\gi
nkgo\build\reference\test\matrix\reference_test_matrix_dense_kernels.vcxproj]
          with
          [
              T=const gko::Executor
          ]

in gtest-printer.h(439), the type is const gko::Executor, which is not printable via os << obj; It selects StreamPrinter for const gko::Executor, but it should not select this class because decltype(std::declval<std::ostream&>() << std::declval<const T&>())> is failed. Also, I do not know why it calls std::linear_congruential from gtest-printer.h(310); If I changes gtest-printer.h(213) to *os << "1";, it works.

asoffer commented 2 years ago

My guess here is that operator<< for std::ranlux48 is not properly SFINAE guarded. When the universal printer attempts to instantiate operator<<, it attempts and substitution succeeds, but instantiation fails, generating the error. This works just fine with GCC and Clang today as well as MSVC 19.14, but starts failing at MSVC 19.15. [Godbolt Link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:13,positionColumn:2,positionLineNumber:13,selectionStartColumn:1,selectionStartLineNumber:13,startColumn:1,startLineNumber:13),source:'%23include+%3Crandom%3E%0A%23include+%22gtest/gtest.h%22%0A%0Astruct+Dummy%7B%0A++friend+bool+operator%3D%3D(Dummy,+Dummy)%3B%0A%7D%3B%0A%0Avoid+f()+%7B%0A++Dummy+a%3B%0A++EXPECT_EQ(a,+a)%3B%0A+%0A++std::ranlux48+rand_engine%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:conformance,i:(compilers:!((compilerId:vcpp_v19_14_x64,options:''),(compilerId:vcpp_v19_15_x64,options:''),(compilerId:clang_trunk,options:''),(compilerId:gsnapshot,options:'')),editorid:1,langId:c%2B%2B,libs:!((name:googletest,ver:trunk))),l:'5',n:'0',o:'Conformance+Viewer+(Editor+%231)+4/10',t:'0')),header:(),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4). It also works fine with other engines. For that reason, I suspect this is a bug in MSVC, and I'd suggest bringing it up there.