Adrian Tong via llvm-dev
2019-Jun-09 02:46 UTC
[llvm-dev] Strange local variable cv::VideoCapture allocated
Hi I am using clang-6 to compile this C++ code and I see a strange temporary variable allocated at expression address 0x7ff1131536e8. If I change the ternary operator at line 483 to an if-else, the temporary is not allocated. Thanks Variables: ======== FFMPEGVideoCapture ffmpeg_video_capture_; cv::VideoCapture opencv_video_capture_; Function: ======= bool StreamData::readFileFrame(Mat& curr_frame, int& frame_id) { // read frame from file ++frame_id; 483: enable_ffmpeg_decoder_ ? (ffmpeg_video_capture_.read(curr_frame)) : opencv_video_capture_ >> curr_frame; return !curr_frame.empty(); } Generated AST from ast-dump: ========================== -CXXMethodDecl 0x7ff113148810 parent 0x7ff114400cb0 prev 0x7ff114401e30 <line:480:1, line:486:1> line:480:18 used readFileFrame 'bool (cv::Mat &, int &)' | |-ParmVarDecl 0x7ff113148708 <col:32, col:37> col:37 used curr_frame 'cv::Mat &' | |-ParmVarDecl 0x7ff113148780 <col:49, col:54> col:54 used frame_id 'int &' | `-CompoundStmt 0x7ff1131537d8 <col:64, line:486:1> | |-UnaryOperator 0x7ff113148930 <line:482:5, col:7> 'int' lvalue prefix '++' | | `-DeclRefExpr 0x7ff113148908 <col:7> 'int' lvalue ParmVar 0x7ff113148780 'frame_id' 'int &' | |-ExprWithCleanups 0x7ff1131536e8 <line:483:5, line:484:32> 'cv::VideoCapture' | | `-ConditionalOperator 0x7ff1131536b8 <line:483:5, line:484:32> 'cv::VideoCapture' | | |-ImplicitCastExpr 0x7ff113153178 <line:483:5> 'bool' <LValueToRValue> | | | `-MemberExpr 0x7ff113148968 <col:5> 'bool' lvalue ->enable_ffmpeg_decoder_ 0x7ff114221ef0 | | | `-CXXThisExpr 0x7ff113148950 <col:5> 'xyz::StreamData *' this | | |-CXXBindTemporaryExpr 0x7ff113153620 <col:30, col:69> 'cv::VideoCapture' (CXXTemporary 0x7ff113153618) | | | `-CXXConstructExpr 0x7ff1131535e0 <col:30, col:69> 'cv::VideoCapture' 'void (const cv::VideoCapture &) noexcept(false)' elidable | | | `-MaterializeTemporaryExpr 0x7ff1131535c8 <col:30, col:69> 'const cv::VideoCapture' lvalue | | | `-ImplicitCastExpr 0x7ff1131535b0 <col:30, col:69> 'const cv::VideoCapture' <NoOp> | | | `-CXXBindTemporaryExpr 0x7ff113153590 <col:30, col:69> 'cv::VideoCapture' (CXXTemporary 0x7ff113153588) | | | `-CXXConstructExpr 0x7ff113153550 <col:30, col:69> 'cv::VideoCapture' 'void (const cv::VideoCapture &) noexcept(false)' elidable | | | `-MaterializeTemporaryExpr 0x7ff113153238 <col:30, col:69> 'const cv::VideoCapture' lvalue | | | `-ImplicitCastExpr 0x7ff113153220 <col:30, col:69> 'const cv::VideoCapture' <NoOp> | | | `-CXXBindTemporaryExpr 0x7ff113153200 <col:30, col:69> 'cv::VideoCapture' (CXXTemporary 0x7ff1131531f8) | | | `-ImplicitCastExpr 0x7ff1131531e0 <col:30, col:69> 'cv::VideoCapture' <ConstructorConversion> | | | `-CXXConstructExpr 0x7ff1131531a8 <col:30, col:69> 'cv::VideoCapture' 'void (int)' | | | `-ImplicitCastExpr 0x7ff113153190 <col:30, col:69> 'int' <IntegralCast> | | | `-ParenExpr 0x7ff113148a80 <col:30, col:69> 'bool' | | | `-CXXMemberCallExpr 0x7ff113148a50 <col:31, col:68> 'bool' | | | |-MemberExpr 0x7ff1131489f0 <col:31, col:53> '<bound member function type>' .read 0x7ff1143a6f38 | | | | `-MemberExpr 0x7ff1131489b8 <col:31> 'FFMPEGVideoCapture' lvalue ->ffmpeg_video_capture_ 0x7ff114402a38 | | | | `-CXXThisExpr 0x7ff1131489a0 <col:31> 'xyz::StreamData *' this | | | `-DeclRefExpr 0x7ff113148a28 <col:58> 'cv::Mat' lvalue ParmVar 0x7ff113148708 'curr_frame' 'cv::Mat &' | | `-CXXBindTemporaryExpr 0x7ff113153698 <line:484:7, col:32> 'cv::VideoCapture' (CXXTemporary 0x7ff113153690) | | `-CXXConstructExpr 0x7ff113153658 <col:7, col:32> 'cv::VideoCapture' 'void (const cv::VideoCapture &) noexcept(false)' | | `-ImplicitCastExpr 0x7ff113153640 <col:7, col:32> 'const cv::VideoCapture' lvalue <NoOp> | | `-CXXOperatorCallExpr 0x7ff113153130 <col:7, col:32> 'cv::VideoCapture' lvalue | | |-ImplicitCastExpr 0x7ff113153118 <col:29> 'cv::VideoCapture &(*)(cv::Mat &)' <FunctionToPointerDecay> | | | `-DeclRefExpr 0x7ff1131530c0 <col:29> 'cv::VideoCapture &(cv::Mat &)' lvalue CXXMethod 0x55be741b2b60 'operator>>' 'cv::VideoCapture &(cv::Mat &)' | | |-MemberExpr 0x7ff113148ab8 <col:7> 'cv::VideoCapture':'cv::VideoCapture' lvalue ->opencv_video_capture_ 0x7ff114402b00 | | | `-CXXThisExpr 0x7ff113148aa0 <col:7> 'xyz::StreamData *' this | | `-DeclRefExpr 0x7ff113148af0 <col:32> 'cv::Mat' lvalue ParmVar 0x7ff113148708 'curr_frame' 'cv::Mat &' -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190608/f6793ebb/attachment.html>
Tim Northover via llvm-dev
2019-Jun-09 09:02 UTC
[llvm-dev] Strange local variable cv::VideoCapture allocated
Hi Adrian, This question would probably be better in cfe-dev since it's about Clang and the C++ AST rather than anything LLVM, but I'll do my best... On Sun, 9 Jun 2019 at 03:47, Adrian Tong via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I am using clang-6 to compile this C++ code and I see a strange temporary variable allocated at expression address 0x7ff1131536e8.There are several temporaries in that code, and that address represents none of them (or all, if you prefer). The easiest one to explain is from the most deeply nested at 0x7ff113153200. It's because the conditional operator is an expression, which means it has to produce a value with a single, well-specified type. In this case the LHS (read call) wants to be a bool and the RHS wants to be a cv::VideoCapture. According to C++ rules that bool can be implicitly converted to a cv::VideoCapture via one of its constructors (which takes an int). So cv::VideoCapture is chosen as the final type and Clang materializes temporaries to produce a value with that type. That's probably not what you want. I'm afraid I don't know about the outer temporaries. Definitely one for cfe-dev. Cheers. Tim.
Adrian Tong via llvm-dev
2019-Jun-10 16:53 UTC
[llvm-dev] Strange local variable cv::VideoCapture allocated
On Sun, 9 Jun 2019 at 02:02, Tim Northover <t.p.northover at gmail.com> wrote:> Hi Adrian, > > This question would probably be better in cfe-dev since it's about > Clang and the C++ AST rather than anything LLVM, but I'll do my > best... > > On Sun, 9 Jun 2019 at 03:47, Adrian Tong via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > I am using clang-6 to compile this C++ code and I see a strange > temporary variable allocated at expression address 0x7ff1131536e8. > > There are several temporaries in that code, and that address > represents none of them (or all, if you prefer). > > The easiest one to explain is from the most deeply nested at > 0x7ff113153200. It's because the conditional operator is an > expression, which means it has to produce a value with a single, > well-specified type. In this case the LHS (read call) wants to be a > bool and the RHS wants to be a cv::VideoCapture. > > According to C++ rules that bool can be implicitly converted to a > cv::VideoCapture via one of its constructors (which takes an int). So > cv::VideoCapture is chosen as the final type and Clang materializes > temporaries to produce a value with that type. That's probably not > what you want. > > I'm afraid I don't know about the outer temporaries. Definitely one for > cfe-dev. > > Cheers. > > Tim. >Got it. Thank you Tim. This is what I need. I will send future questions like this to cfe-dev. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190610/b4f9354d/attachment.html>