首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在函数参数中使用赋值运算符会失败?

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

Stack Overflow用户
提问于 2017-05-12 01:41:36
回答 1查看 100关注 0票数 0

有人能指出为什么在下面的代码中,在传递给p_char SIGSEGV时使用带有“返回rvalue”样式的变量write()吗?

代码语言:javascript
复制
#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;
}

如果我改变以下两行..。

代码语言:javascript
复制
const char* p_char;
result = write( sp[ 1 ], ( p_char = "Hello?" ), strlen( p_char ) );

...to这个..。

代码语言:javascript
复制
const char* p_char = "Hello?";
result = write( sp[ 1 ], p_char, strlen( p_char ) );

...then程序没有SIGSEGV并优雅地退出。

编译测试gcc 4.8.3和4.9.2 (守则厨师)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-12 01:44:34

函数参数的计算顺序未定义(至少在C++14和更早版本中如此)。

所以在

代码语言:javascript
复制
result = write( sp[ 1 ], ( p_char = "Hello?" ), strlen( p_char ) );

strlen( p_char )可能在p_char = "Hello?"之前进行评估,从而导致灾难。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43928032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档