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