FALLTHROUGH —— ArduPilot —— switch_case代码理解

版权声明:本文为博主原创博文,未经允许不得转载,若要转载,请说明出处并给出博文链接  

switch (effective_mode) 
    {
    case AUTO:
        handle_auto_mode();
        break;

    case AVOID_ADSB:
    case GUIDED:
        if (auto_state.vtol_loiter && quadplane.available()) {
            quadplane.guided_update();
            break;
        }
        FALLTHROUGH;  //中文翻译:落到

    case RTL:
    case LOITER:
        calc_nav_roll();
        calc_nav_pitch();
        calc_throttle();
        break;
 switch(control_mode) {
    case AUTO:
        if (ahrs.home_is_set()) {
            mission.update();
        }
        break;
            
    case RTL:
        if (quadplane.available() && quadplane.rtl_mode == 1 &&
            (nav_controller->reached_loiter_target() ||
             location_passed_point(current_loc, prev_WP_loc, next_WP_loc) ||
             auto_state.wp_distance < MAX(qrtl_radius, quadplane.stopping_distance())) &&
            AP_HAL::millis() - last_mode_change_ms > 1000) {
            /*
              for a quadplane in RTL mode we switch to QRTL when we
              are within the maximum of the stopping distance and the
              RTL_RADIUS
             */
            set_mode(QRTL, MODE_REASON_UNKNOWN);
            break;
        } else if (g.rtl_autoland == 1 &&
            !auto_state.checked_for_autoland &&
            reached_loiter_target() && 
            labs(altitude_error_cm) < 1000) {
            // we've reached the RTL point, see if we have a landing sequence
            if (mission.jump_to_landing_sequence()) {
                // switch from RTL -> AUTO
                set_mode(AUTO, MODE_REASON_UNKNOWN);
            }

            // prevent running the expensive jump_to_landing_sequence
            // on every loop
            auto_state.checked_for_autoland = true;
        }
        else if (g.rtl_autoland == 2 &&
            !auto_state.checked_for_autoland) {
            // Go directly to the landing sequence
            if (mission.jump_to_landing_sequence()) {
                // switch from RTL -> AUTO
                set_mode(AUTO, MODE_REASON_UNKNOWN);
            }

            // prevent running the expensive jump_to_landing_sequence
            // on every loop
            auto_state.checked_for_autoland = true;
        }
        radius = abs(g.rtl_radius);
        if (radius > 0) {
            loiter.direction = (g.rtl_radius < 0) ? -1 : 1;
        }
        // fall through to LOITER  落到LOITER
        FALLTHROUGH;

    case LOITER:
    case AVOID_ADSB:
    case GUIDED:
        update_loiter(radius);
        break;

    case CRUISE:
        update_cruise();
        break;

    case MANUAL:
    case STABILIZE:
    case TRAINING:
    case INITIALISING:
    case ACRO:
    case FLY_BY_WIRE_A:
    case AUTOTUNE:
    case FLY_BY_WIRE_B:
    case CIRCLE:
    case QSTABILIZE:
    case QHOVER:
    case QLOITER:
    case QLAND:
    case QRTL:
        // nothing to do
        break;
    }

针对上述两段代码中的FALLTHROUGH以及注释分析,可以大致推测出,switch case语句中如果出现FALLTHROUGH语句,就相当于直接继续执行下一个case,直到遇见break,退出swich语句。

继续追踪FALLTHROUGH,可以追踪到AP_common.h文件中的如下代码段

#ifdef __has_cpp_attribute
#  if __has_cpp_attribute(fallthrough)
#    define FALLTHROUGH [[fallthrough]]
#  elif __has_cpp_attribute(gnu::fallthrough)
#    define FALLTHROUGH [[gnu::fallthrough]]
#  endif
#endif
#ifndef FALLTHROUGH
#  define FALLTHROUGH
#endif

可以看到如果定义__has_cpp_attribute 且如果 __has_cpp_attribute(fallthrough)为真,那么就定义FALLTHROUGH 为 [[fallthrough]]。 如果没有定义FALLTHROUGH,那么就定义FALLTHROUGH。

仅仅从字面理解,我们可以知道这是一种c++的属性。

继续对上述代码查询搜索,我们可以查到如下,可以证实我们上述的分析。

网址:http://gcc.gnu.org/projects/cxx-status.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Go语言中,switch case语句是一种条件语句,用于根据不同的条件执行不同的代码块。它类似于其他编程语言中的switch语句,但Go语言的switch case语句有一些独特的特点和语法。 Go语言的switch case语句的基本语法如下: ```go switch expression { case value1: // 执行当expression等于value1时的代码 case value2: // 执行当expression等于value2时的代码 ... default: // 执行当expression不匹配任何case时的代码 } ``` switch表达式可以是整数、字符串、布尔值等任何可以被比较的值。case后面的值与switch表达式进行比较,如果匹配则执行对应的代码块。如果没有匹配的case,则执行default代码块(如果有的话)。 以下是一个简单的示例,展示了如何使用switch case语句: ```go x := 3 result := &quot;&quot; switch x { case 1: result = &quot;x is 1&quot; case 2: result = &quot;x is 2&quot; case 3: result = &quot;x is 3&quot; default: result = &quot;x is not 1, 2 or 3&quot; } fmt.Println(result) // 输出: x is 3 ``` 在上面的示例中,根据变量x的值,执行了不同的case代码块,并最终将结果存储在result变量中。如果没有匹配的case,则执行default代码块。 需要注意的是,Go语言的switch case语句是大小写敏感的,因此必须确保case值的大小写与switch表达式的值完全匹配。此外,每个case后面的代码块只能执行一次,即使表达式的值与多个case的值匹配。如果需要多次执行相同的代码块,可以使用fallthrough关键字将下一个case继续连接到当前case的末尾。 希望这个简单的介绍对你有所帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值