Invalid scale size. Cannot be less than zero

今天遇到Invalid scale size. Cannot be less than zero 这么个问题。之前也遇到过,具体什么原因也没有查看,网上找一些方法就解决了。

java.sql.SQLException: Invalid scale size. Cannot be less than zero

问题原因:
jdbc驱动的一个bug. 网上几乎大部分的解释是对于number类型的值支持有问题。

count(), sum() 等这种集合函数的使用, 使得返回的结果有问题。(解决方法1

 

还有就是针对不是集合的,今天遇到的就是这么样情况,之前是把某个数据munber的精度修改就是了,

而今天的是跨数据库的操作两个系统的整合操作,另一个系统只提供了sql语句并且包含视图。这次我就没办法像之前

那样去修改字段的精度了。但是并不是没有解决方法,(见解决方法2).

 

解决方法

1. 集合解决

 

SELECT count(..),  ...  

 

需要修改成 

 

SELECT count(..) + 0, ...  

 

2.jdbc驱动的一个bug对于number类型的值支持有问题

 

这里我们不讨论为什么,只讨论如何修改。

 

对于只是某个字段的number的问题,我们可以在数据库中修改其精度。

对于不能修改表的数据结构的 我们 可以在number字段里面有数值型的字段,将其TO_CHAR之后,就OK了。

/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/audio_coding/neteq/delay_manager.h" #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <memory> #include <numeric> #include <string> #include "modules/audio_coding/neteq/histogram.h" #include "modules/include/module_common_types_public.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/numerics/safe_minmax.h" #include "system_wrappers/include/field_trial.h" namespace { constexpr int kMinBaseMinimumDelayMs = 0; constexpr int kMaxBaseMinimumDelayMs = 10000; constexpr int kMaxReorderedPackets = 10; // Max number of consecutive reordered packets. constexpr int kMaxHistoryMs = 2000; // Oldest packet to include in history to // calculate relative packet arrival delay. constexpr int kDelayBuckets = 100; constexpr int kBucketSizeMs = 20; constexpr int kDecelerationTargetLevelOffsetMs = 85 << 8; // In Q8. int PercentileToQuantile(double percentile) { return static_cast<int>((1 << 30) * percentile / 100.0 + 0.5); } struct DelayHistogramConfig { int quantile = 1041529569; // 0.97 in Q30. int forget_factor = 32745; // 0.9993 in Q15. absl::optional<double> start_forget_weight = 2; }; DelayHistogramConfig GetDelayHistogramConfig() { constexpr char kDelayHistogramFieldTrial[] = "WebRTC-Audio-NetEqDelayHistogram"; DelayHistogramConfig config; if (webrtc::field_trial::IsEnabled(kDelayHistogramFieldTrial)) { const auto field_trial_string = webrtc::field_trial::FindFullName(kDelayHistogramFieldTrial); double percentile = -1.0; double forget_factor = -1.0; double start_forget_weight = -1.0; if (sscanf(field_trial_string.c_str(), "Enabled-%lf-%lf-%lf", &percentile, &forget_factor, &start_forget_weight) >= 2 && percentile >= 0.0 && percentile <= 100.0 && forget_factor >= 0.0 && forget_factor <= 1.0) { config.quantile = PercentileToQuantile(percentile); config.forget_factor = (1 << 15) * forget_factor; config.start_forget_weight = start_forget_weight >= 1 ? absl::make_optional(start_forget_weight) : absl::nullopt; } } RTC_LOG(LS_INFO) << "Delay histogram config:" " quantile=" << config.quantile << " forget_factor=" << config.forget_factor << " start_forget_weight=" << config.start_forget_weight.value_or(0); return config; } } // namespace namespace webrtc { DelayManager::DelayManager(size_t max_packets_in_buffer, int base_minimum_delay_ms, int histogram_quantile, bool enable_rtx_handling, const TickTimer* tick_timer, std::unique_ptr<Histogram> histogram) : first_packet_received_(false), max_packets_in_buffer_(max_packets_in_buffer), histogram_(std::move(histogram)), histogram_quantile_(histogram_quantile), tick_timer_(tick_timer), base_minimum_delay_ms_(base_minimum_delay_ms), effective_minimum_delay_ms_(base_minimum_delay_ms), base_target_level_(4), // In Q0 domain. target_level_(base_target_level_ << 8), // In Q8 domain. packet_len_ms_(0), last_seq_no_(0), last_timestamp_(0), minimum_delay_ms_(0), maximum_delay_ms_(0), last_pack_cng_or_dtmf_(1), enable_rtx_handling_(enable_rtx_handling) { RTC_CHECK(histogram_); RTC_DCHECK_GE(base_minimum_delay_ms_, 0); Reset(); } std::unique_ptr<DelayManager> DelayManager::Create( size_t max_packets_in_buffer, int base_minimum_delay_ms, bool enable_rtx_handling, const TickTimer* tick_timer) { DelayHistogramConfig config = GetDelayHistogramConfig(); const int quantile = config.quantile; std::unique_ptr<Histogram> histogram = std::make_unique<Histogram>( kDelayBuckets, config.forget_factor, config.start_forget_weight); return std::make_unique<DelayManager>( max_packets_in_buffer, base_minimum_delay_ms, quantile, enable_rtx_handling, tick_timer, std::move(histogram)); } DelayManager::~DelayManager() {} absl::optional<int> DelayManager::Update(uint16_t sequence_number, uint32_t timestamp, int sample_rate_hz) { if (sample_rate_hz <= 0) { return absl::nullopt; } if (!first_packet_received_) { // Prepare for next packet arrival. packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_seq_no_ = sequence_number; last_timestamp_ = timestamp; first_packet_received_ = true; return absl::nullopt; } // Try calculating packet length from current and previous timestamps. int packet_len_ms; if (!IsNewerTimestamp(timestamp, last_timestamp_) || !IsNewerSequenceNumber(sequence_number, last_seq_no_)) { // Wrong timestamp or sequence order; use stored value. packet_len_ms = packet_len_ms_; } else { // Calculate timestamps per packet and derive packet length in ms. int64_t packet_len_samp = static_cast<uint32_t>(timestamp - last_timestamp_) / static_cast<uint16_t>(sequence_number - last_seq_no_); packet_len_ms = rtc::saturated_cast<int>(1000 * packet_len_samp / sample_rate_hz); } bool reordered = false; absl::optional<int> relative_delay; if (packet_len_ms > 0) { // Cannot update statistics unless |packet_len_ms| is valid. // Inter-arrival time (IAT) in integer "packet times" (rounding down). This // is the value added to the inter-arrival time histogram. int iat_ms = packet_iat_stopwatch_->ElapsedMs(); // Check for discontinuous packet sequence and re-ordering. if (IsNewerSequenceNumber(sequence_number, last_seq_no_ + 1)) { // Compensate for gap in the sequence numbers. Reduce IAT with the // expected extra time due to lost packets. int packet_offset = static_cast<uint16_t>(sequence_number - last_seq_no_ - 1); iat_ms -= packet_offset * packet_len_ms; } else if (!IsNewerSequenceNumber(sequence_number, last_seq_no_)) { int packet_offset = static_cast<uint16_t>(last_seq_no_ + 1 - sequence_number); iat_ms += packet_offset * packet_len_ms; reordered = true; } int iat_delay = iat_ms - packet_len_ms; if (reordered) { relative_delay = std::max(iat_delay, 0); } else { UpdateDelayHistory(iat_delay, timestamp, sample_rate_hz); relative_delay = CalculateRelativePacketArrivalDelay(); } const int index = relative_delay.value() / kBucketSizeMs; if (index < histogram_->NumBuckets()) { // Maximum delay to register is 2000 ms. histogram_->Add(index); } // Calculate new |target_level_| based on updated statistics. target_level_ = CalculateTargetLevel(); LimitTargetLevel(); } // End if (packet_len_ms > 0). if (enable_rtx_handling_ && reordered && num_reordered_packets_ < kMaxReorderedPackets) { ++num_reordered_packets_; return relative_delay; } num_reordered_packets_ = 0; // Prepare for next packet arrival. packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_seq_no_ = sequence_number; last_timestamp_ = timestamp; return relative_delay; } void DelayManager::UpdateDelayHistory(int iat_delay_ms, uint32_t timestamp, int sample_rate_hz) { PacketDelay delay; delay.iat_delay_ms = iat_delay_ms; delay.timestamp = timestamp; delay_history_.push_back(delay); while (timestamp - delay_history_.front().timestamp > static_cast<uint32_t>(kMaxHistoryMs * sample_rate_hz / 1000)) { delay_history_.pop_front(); } } int DelayManager::CalculateRelativePacketArrivalDelay() const { // This effectively calculates arrival delay of a packet relative to the // packet preceding the history window. If the arrival delay ever becomes // smaller than zero, it means the reference packet is invalid, and we // move the reference. int relative_delay = 0; for (const PacketDelay& delay : delay_history_) { relative_delay += delay.iat_delay_ms; relative_delay = std::max(relative_delay, 0); } return relative_delay; } // Enforces upper and lower limits for |target_level_|. The upper limit is // chosen to be minimum of i) 75% of |max_packets_in_buffer_|, to leave some // headroom for natural fluctuations around the target, and ii) equivalent of // |maximum_delay_ms_| in packets. Note that in practice, if no // |maximum_delay_ms_| is specified, this does not have any impact, since the // target level is far below the buffer capacity in all reasonable cases. // The lower limit is equivalent of |effective_minimum_delay_ms_| in packets. // We update |least_required_level_| while the above limits are applied. // TODO(hlundin): Move this check to the buffer logistics class. void DelayManager::LimitTargetLevel() { if (packet_len_ms_ > 0 && effective_minimum_delay_ms_ > 0) { int minimum_delay_packet_q8 = (effective_minimum_delay_ms_ << 8) / packet_len_ms_; target_level_ = std::max(target_level_, minimum_delay_packet_q8); } if (maximum_delay_ms_ > 0 && packet_len_ms_ > 0) { int maximum_delay_packet_q8 = (maximum_delay_ms_ << 8) / packet_len_ms_; target_level_ = std::min(target_level_, maximum_delay_packet_q8); } // Shift to Q8, then 75%.; int max_buffer_packets_q8 = static_cast<int>((3 * (max_packets_in_buffer_ << 8)) / 4); target_level_ = std::min(target_level_, max_buffer_packets_q8); // Sanity check, at least 1 packet (in Q8). target_level_ = std::max(target_level_, 1 << 8); } int DelayManager::CalculateTargetLevel() { int limit_probability = histogram_quantile_; int bucket_index = histogram_->Quantile(limit_probability); int target_level = 1; if (packet_len_ms_ > 0) { target_level += bucket_index * kBucketSizeMs / packet_len_ms_; } base_target_level_ = target_level; // Sanity check. |target_level| must be strictly positive. target_level = std::max(target_level, 1); // Scale to Q8 and assign to member variable. target_level_ = target_level << 8; return target_level_; } int DelayManager::SetPacketAudioLength(int length_ms) { if (length_ms <= 0) { RTC_LOG_F(LS_ERROR) << "length_ms = " << length_ms; return -1; } packet_len_ms_ = length_ms; packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_pack_cng_or_dtmf_ = 1; // TODO(hlundin): Legacy. Remove? return 0; } void DelayManager::Reset() { packet_len_ms_ = 0; // Packet size unknown. histogram_->Reset(); delay_history_.clear(); base_target_level_ = 4; target_level_ = base_target_level_ << 8; packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_pack_cng_or_dtmf_ = 1; } void DelayManager::ResetPacketIatCount() { packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); } void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const { BufferLimits(target_level_, lower_limit, higher_limit); } // Note that |low_limit| and |higher_limit| are not assigned to // |minimum_delay_ms_| and |maximum_delay_ms_| defined by the client of this // class. They are computed from |target_level| in Q8 and used for decision // making. void DelayManager::BufferLimits(int target_level, int* lower_limit, int* higher_limit) const { if (!lower_limit || !higher_limit) { RTC_LOG_F(LS_ERROR) << "NULL pointers supplied as input"; assert(false); return; } // |target_level| is in Q8 already. *lower_limit = (target_level * 3) / 4; if (packet_len_ms_ > 0) { *lower_limit = std::max(*lower_limit, target_level - kDecelerationTargetLevelOffsetMs / packet_len_ms_); } int window_20ms = 0x7FFF; // Default large value for legacy bit-exactness. if (packet_len_ms_ > 0) { window_20ms = (20 << 8) / packet_len_ms_; } // |higher_limit| is equal to |target_level|, but should at // least be 20 ms higher than |lower_limit|. *higher_limit = std::max(target_level, *lower_limit + window_20ms); } int DelayManager::TargetLevel() const { return target_level_; } void DelayManager::LastDecodedWasCngOrDtmf(bool it_was) { if (it_was) { last_pack_cng_or_dtmf_ = 1; } else if (last_pack_cng_or_dtmf_ != 0) { last_pack_cng_or_dtmf_ = -1; } } void DelayManager::RegisterEmptyPacket() { ++last_seq_no_; } bool DelayManager::IsValidMinimumDelay(int delay_ms) const { return 0 <= delay_ms && delay_ms <= MinimumDelayUpperBound(); } bool DelayManager::IsValidBaseMinimumDelay(int delay_ms) const { return kMinBaseMinimumDelayMs <= delay_ms && delay_ms <= kMaxBaseMinimumDelayMs; } bool DelayManager::SetMinimumDelay(int delay_ms) { if (!IsValidMinimumDelay(delay_ms)) { return false; } minimum_delay_ms_ = delay_ms; UpdateEffectiveMinimumDelay(); return true; } bool DelayManager::SetMaximumDelay(int delay_ms) { // If |delay_ms| is zero then it unsets the maximum delay and target level is // unconstrained by maximum delay. if (delay_ms != 0 && (delay_ms < minimum_delay_ms_ || delay_ms < packet_len_ms_)) { // Maximum delay shouldn't be less than minimum delay or less than a packet. return false; } maximum_delay_ms_ = delay_ms; UpdateEffectiveMinimumDelay(); return true; } bool DelayManager::SetBaseMinimumDelay(int delay_ms) { if (!IsValidBaseMinimumDelay(delay_ms)) { return false; } base_minimum_delay_ms_ = delay_ms; UpdateEffectiveMinimumDelay(); return true; } int DelayManager::GetBaseMinimumDelay() const { return base_minimum_delay_ms_; } int DelayManager::base_target_level() const { return base_target_level_; } int DelayManager::last_pack_cng_or_dtmf() const { return last_pack_cng_or_dtmf_; } void DelayManager::set_last_pack_cng_or_dtmf(int value) { last_pack_cng_or_dtmf_ = value; } void DelayManager::UpdateEffectiveMinimumDelay() { // Clamp |base_minimum_delay_ms_| into the range which can be effectively // used. const int base_minimum_delay_ms = rtc::SafeClamp(base_minimum_delay_ms_, 0, MinimumDelayUpperBound()); effective_minimum_delay_ms_ = std::max(minimum_delay_ms_, base_minimum_delay_ms); } int DelayManager::MinimumDelayUpperBound() const { // Choose the lowest possible bound discarding 0 cases which mean the value // is not set and unconstrained. int q75 = MaxBufferTimeQ75(); q75 = q75 > 0 ? q75 : kMaxBaseMinimumDelayMs; const int maximum_delay_ms = maximum_delay_ms_ > 0 ? maximum_delay_ms_ : kMaxBaseMinimumDelayMs; return std::min(maximum_delay_ms, q75); } int DelayManager::MaxBufferTimeQ75() const { const int max_buffer_time = max_packets_in_buffer_ * packet_len_ms_; return rtc::dchecked_cast<int>(3 * max_buffer_time / 4); } } // namespace webrtc 解释在干嘛
最新发布
10-12
<think>好的,我现在需要帮助用户解决IAR编译器中出现的“array size must be greater than zero”错误。首先,我得理解这个错误的原因。通常,数组的大小必须是一个正整数,所以当编译器检测到数组的大小为零或负数时,就会报这个错误。可能的情况包括: 1. **显式声明大小为0的数组**:比如用户可能在代码中写了类似`int array[0];`这样的定义,这显然不合法。 2. **使用宏或常量导致大小为0**:可能用户用了一个宏定义或常量来指定数组大小,但这个值在某个情况下被计算为0,尤其是在条件编译中,比如`#define SIZE 0`然后`int arr[SIZE];`。 3. **动态计算数组大小结果为非正数**:比如在C99或C11中允许的动态数组(VLA),如果计算出来的大小是非正数,就会出错。例如`int n = 0; int arr[n];`。 4. **模板元编程中的错误**:如果是C++,可能在模板或constexpr中计算数组大小时出现了错误,导致结果非正。 5. **编译器配置问题**:可能项目配置中某些宏定义覆盖了用户预期的值,导致数组大小被错误地设置为0。 接下来,我需要考虑如何引导用户排查这些问题。可能需要分步骤建议用户检查代码中数组声明的位置,确认数组大小的来源是否是常量表达式,或者是否有可能在运行时计算出非正值。另外,检查预处理器的宏定义,查看是否有条件编译导致某些情况下SIZE为0。对于VLA的情况,需要确认编译器是否支持,并且n的值是否总为正数。 可能还需要检查代码中的分支,特别是当数组大小依赖于某些条件或函数返回值时,是否有可能导致大小为0的情况。例如,如果数组大小是根据某个计算结果来的,而这个计算可能返回0或负数,那么需要添加检查确保大小为正。 用户可能需要查看具体的代码行,所以建议他们检查报错提示中的文件和行号,定位到具体的数组声明。然后检查该数组的大小是如何确定的,是否有可能为0。如果是宏定义,可能需要追踪宏的展开,或者检查是否有多个宏定义冲突的情况。 此外,IAR编译器可能有特定的限制或扩展,需要查阅IAR的文档,确认是否有特殊的地方需要注意。例如,某些编译器可能不允许VLA,或者在特定模式下才会支持,需要确保编译选项正确。 最后,可能的解决方案包括:确保数组大小是正整数常量,避免使用可能导致0的动态计算,检查宏定义和条件编译,使用静态断言确保大小合法,或者在C++中使用constexpr或模板参数来确保编译期正值。</think>针对IAR编译器中"array size must be greater than zero"错误的解决方案,请按照以下步骤排查: ### 一、错误原因分析 该错误发生在以下三种典型场景: 1. **显式零长度声明**:`uint8_t array[0];`(C99标准禁止零长度数组[^1]) 2. **宏定义展开异常**: ```c #define BUFFER_SIZE 0 // 错误示例 uint8_t buffer[BUFFER_SIZE]; ``` 3. **动态计算异常**: ```c const int size = calculate_size(); // 计算结果<=0时触发 uint8_t dynamic_array[size]; // C99 VLA特性需谨慎使用 ``` ### 二、解决方案步骤 1. **定位错误位置** - 查看编译错误提示的源文件路径和行号 - 示例错误格式: ``` Error[Pe028]: array size must be greater than zero in file: src/main.c line 42 ``` 2. **检查数组声明类型** - **静态数组**:确保大小是编译期正整型常量 ```c // 正确示例(C语言) #define VALID_SIZE 10 static uint8_t valid_array[VALID_SIZE]; ``` - **动态数组**:确认编译器支持VLA(IAR默认禁用) ```c // 需开启C99模式并添加编译选项 // Project > Options > C/C++ Compiler > Language: C99 ``` 3. **宏定义检查(关键步骤)** ```c // 使用预处理检查 #if BUFFER_SIZE <= 0 #error "BUFFER_SIZE must be positive" #endif ``` 4. **模板特化处理(C++项目)** ```cpp template <int N> struct SafeArray { static_assert(N > 0, "Array size must be positive"); uint8_t data[N]; }; ``` ### 三、工程配置建议 1. **编译器选项验证** ``` Project > Options > C/C++ Compiler > Language - C dialect: C99 (推荐) - Allow VLA: Enabled(慎用) ``` 2. **静态断言防护** ```c _Static_assert(SIZE > 0, "Array size invalid"); // C11标准 ``` ### 四、特殊案例处理 **条件编译导致的零长度:** ```c #if defined(DEBUG_MODE) #define TEMP_BUFFER_SIZE 0 // 调试模式下错误配置 #else #define TEMP_BUFFER_SIZE 256 #endif ``` **修正方案:** ```c #ifdef DEBUG_MODE #define TEMP_BUFFER_SIZE 256 // 即使调试模式也应保持有效长度 #else #define TEMP_BUFFER_SIZE 512 #endif ``` ### 五、最佳实践 1. 使用`size_t`类型声明数组长度 2. 对动态计算的长度添加运行时检查: ```c int calculated_size = get_size(); assert(calculated_size > 0 && "Invalid array size"); uint8_t* heap_array = malloc(calculated_size * sizeof(uint8_t)); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值