简体   繁体   English

为什么在函数参数中使用赋值运算符会失败?

[英]Why does this use of assignment operator in a function argument fail?

Can someone point out why, in the following code, using variable p_char with the "return the rvalue" style when passing to write() SIGSEGVs? 有人能说出为什么,在下面的代码,使用可变p_char与“返回右值”传递时的风格write() SIGSEGVs?

#include <iostream>
#include <cerrno>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdint.h>
#include <sstream>
#include <stdexcept>

#define ASSERT( EXPRESSION, SOCKETPAIR ) \
{ \
  if ( ! ( EXPRESSION ) ) \
  { \
    std::ostringstream oss; \
    oss << "Expression \"" << #EXPRESSION << "\" failed at line " << __LINE__ \
        << "; errno == " << errno << " (" << strerror( errno ) << ")"; \
    throw MyException( oss.str(), SOCKETPAIR ); \
  } \
}

class SocketPair
{
public:
  SocketPair()
  {
    memset( socket_, -1, sizeof( socket_ ) );
  }
  int* operator()() { return socket_; }
  int operator[]( const uint32_t idx )
  {
    if ( idx > 1 ) return -1;
    return socket_[ idx ];
  }
private:
  int socket_[ 2 ];
};

class MyException : public std::runtime_error
{
public:
  MyException( const std::string& what_arg, SocketPair& sp )
    : runtime_error( what_arg )
    , sp_( sp )
  {}
  SocketPair& sp_;
};

int main( int argc, char* argv[] )
{
  SocketPair sp;
  try
  {
    int result;

    errno = 0;
    result = socketpair( AF_LOCAL, SOCK_STREAM, 0, sp() );
    ASSERT( result == 0, sp );

    std::cout << "sp[0]==" << sp[0] << ", sp[1]==" << sp[1] << std::endl;

    const char* p_char;
    result = write( sp[ 1 ], ( p_char = "Hello?" ), strlen( p_char ) );
    ASSERT( result == strlen( p_char ), sp );
  }
  catch ( MyException& e )
  {
    std::cout << e.what() << std::endl;
    if ( e.sp_[ 0 ] >= 0 ) close( e.sp_[ 0 ] );
    if ( e.sp_[ 1 ] >= 0 ) close( e.sp_[ 1 ] );
    return 1;
  }

  close( sp[ 0 ] );
  close( sp[ 1 ] );
  return 0;
}

If I change the following two lines... 如果我更改以下两行...

const char* p_char;
result = write( sp[ 1 ], ( p_char = "Hello?" ), strlen( p_char ) );

...to this... ...对此...

const char* p_char = "Hello?";
result = write( sp[ 1 ], p_char, strlen( p_char ) );

...then the program does not SIGSEGV and exits gracefully. ...然后该程序没有SIGSEGV并正常退出。

Compilation tested on gcc 4.8.3 and 4.9.2 (Code Chef). 编译在gcc 4.8.3和4.9.2(代码厨师)上进行了测试。

The order of evaluation of function arguments is undefined (at least in C++14 and earlier). 函数参数的求值顺序是不确定的(至少在C ++ 14和更早的版本中)。

So in 所以在

result = write( sp[ 1 ], ( p_char = "Hello?" ), strlen( p_char ) );

strlen( p_char ) may be evaluated before p_char = "Hello?" strlen( p_char )可以在p_char = "Hello?"之前求值p_char = "Hello?" , resulting in disaster. ,造成灾难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM