用于初始化动态分配的数组的Ada语法

时间:2016-12-02 01:08:41

标签: ada gnat

在Ada中初始化动态分配的数组的正确语法是什么?我试过这个:

C:/Ruby22/lib/ruby/gems/2.2.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcrypt/password.rb in initialize
        raise Errors::InvalidHash.new("invalid hash")
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-bcrypt-ruby-0.0.2/lib/mongoid/bcrypt/ruby.rb in new
        when String then self.new(password)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-bcrypt-ruby-0.0.2/lib/mongoid/bcrypt/ruby.rb in demongoize
        when String then self.new(password)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/fields/standard.rb in demongoize
      delegate :demongoize, :evolve, :mongoize, to: :type
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/fields.rb in block (2 levels) in create_field_getter
              value = field.demongoize(raw)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/validatable.rb in read_attribute_for_validation
        send(attr)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in block in validate
        value = record.read_attribute_for_validation(attribute)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in each
      attributes.each do |attribute|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in validate
      attributes.each do |attribute|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in public_send
            filter.public_send method_to_call, target, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in make_lambda
            filter.public_send method_to_call, target, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
              result_lambda = -> { user_callback.call target, value }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block (2 levels) in halting
              result_lambda = -> { user_callback.call target, value }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
           result_lambda.call if result_lambda.is_a?(Proc)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block (2 levels) in default_terminator
            result_lambda.call if result_lambda.is_a?(Proc)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in catch
      catch(:abort) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in default_terminator
      catch(:abort) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
          env.halted = halted_lambda.call(target, result_lambda)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in halting
          env.halted = halted_lambda.call(target, result_lambda)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
    @before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in call
    @before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in each
    @before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
    @before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in __run_callbacks__
    runner.call(e).value
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in _run_validate_callbacks
          __run_callbacks__(_#{name}_callbacks, &block)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in run_validations!
  _run_validate_callbacks
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations/callbacks.rb in block in run_validations!
    _run_validation_callbacks { super }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in __run_callbacks__
    yield if block_given?
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in _run_validation_callbacks
          __run_callbacks__(_#{name}_callbacks, &block)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations/callbacks.rb in run_validations!
    _run_validation_callbacks { super }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in valid?
  run_validations!
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/validatable.rb in valid?
  super context ? context : (new_record? ? :create : :update)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in invalid?
  !valid?(context)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in prepare_insert
      invalid?(options[:context] || :create)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in insert
    prepare_insert(options) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in block in create!
          doc.fail_due_to_validation! unless doc.insert.errors.empty?
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/threaded/lifecycle.rb in _creating
      yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in create!
      _creating do
C:/Users/ALilland/Documents/macros/experiments/mongoid/mongoid_heroku/db_core_app/models/user.rb in block (2 levels) in <class:Routes>
    User.create!(
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
      proc { |a,p| unbound_method.bind(a).call }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in compile!
      proc { |a,p| unbound_method.bind(a).call }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in []
        route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block (3 levels) in route!
        route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in route_eval
  throw :halt, yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block (2 levels) in route!
        route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in process_route
    block ? block[self, values] : yield(self, values)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
  catch(:pass) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in process_route
  catch(:pass) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in route!
      returned_pass_block = process_route(pattern, keys, conditions) do |*args|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in each
    routes.each do |pattern, keys, conditions, block|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in route!
    routes.each do |pattern, keys, conditions, block|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in dispatch!
    route!
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in invoke
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in invoke
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in dispatch!
  invoke do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in call!
  invoke { dispatch! }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in invoke
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in invoke
  res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call!
  invoke { dispatch! }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
  dup.call!(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb in call
    status, headers, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
    result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
    result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb in call
    app.call env
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb in call
    status, headers, body = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
    result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
    result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb in call
    status, headers, body        = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb in context
      status, headers, body = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb in call
      context(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/logger.rb in call
  @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
  env['sinatra.commonlogger'] ? @app.call(env) : super
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/head.rb in call
status, headers, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/show_exceptions.rb in call
  @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
  result, callback = app.call(env), env['async.callback']
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
  @stack.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in call
    synchronize { prototype.call(env) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in synchronize
      yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
    synchronize { prototype.call(env) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in block in call
    result = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in each
  @apps.each do |app|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in call
  @apps.each do |app|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/tempfile_reaper.rb in call
  status, headers, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/lint.rb in _call
  status, headers, @body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/lint.rb in call
  dup._call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/showexceptions.rb in call
  @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/commonlogger.rb in call
  status, header, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
    call_without_check(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/chunked.rb in call
  status, headers, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/content_length.rb in call
  status, headers, body = @app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in block in pre_process
    response = @app.call(@request.env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in catch
  catch(:async) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in pre_process
  catch(:async) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in process
    post_process(pre_process)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in receive_data
  process if @request.parse(data)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.1-x86-mingw32/lib/eventmachine.rb in run_machine
      run_machine
C:/Ruby22/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.1-x86-mingw32/lib/eventmachine.rb in run
      run_machine
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/backends/base.rb in start
      EventMachine.run(&starter)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/server.rb in start
  @backend.start { setup_signals if @setup_signals }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/handler/thin.rb in run
    server.start
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/server.rb in start
  server.run wrapped_app, options, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/server.rb in start
  new(options).start
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/bin/rackup in <top (required)>
  Rack::Server.start
C:/Ruby22/bin/rackup in load
  load Gem.bin_path('rack', 'rackup', version)
C:/Ruby22/bin/rackup in <main>
  load Gem.bin_path('rack', 'rackup', version)

导致编译器错误 - “二元运算符预期”。这个:

type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound)'(others => 0);

这似乎令人惊讶地提升了一个SEGFAULT。不确定那里发生了什么,但想在我开始追逐我的尾巴之前获得正确的语法。

3 个答案:

答案 0 :(得分:5)

如果您使用的是Ada2012,则可以执行以下操作:

type Short_Array is array(Natural range <>) of Short with
   Default_Component_Value => 0;
Items : access Short_Array := new Short_Array(1..UpperBound);

在Ada 2012 Rationale http://www.ada-auth.org/standards/12rat/html/Rat12-2-6.html

的第2.6节中解释了数组的默认初始值的使用

答案 1 :(得分:3)

Ada的另一种方法是将记录定义为判别式记录,判别式确定数组字段的大小。

type Items_Record (Size : Natural) is record
   -- Some non-array fields of your record
   Items : Short_Array(1..Size);
end record;

然后可以在内部块

中分配记录的实例
Get(Items_Size);
declare
   My_Record : Items_Record(Size => Items_Size);
begin
   -- Process the instance of Items_Record
end;

记录在堆栈上动态分配。如果记录大小非常大,您将遇到堆栈溢出问题。如果没有,这非常有效。这种方法的一个优点是,当到达块的末尾时,实例会自动解除分配。

答案 2 :(得分:0)

第二个示例中的SEGFAULT最有可能来自初始化。

比较

type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
Items.all := (others => 0);

这:

type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
for I in 1..UpperBound loop
   Items(I) := 0;
end loop;

并使用ulimit -Ss的不同值进行设置,以设置允许的堆栈大小。

重点是

Items.all := (others => 0);

在堆栈上分配一个数组,并将其复制到堆分配的数组中。因此,您认为您正在堆上工作,但仍需要大量堆栈。如果您的数组对于您的ulimit -Ss太大(或同时考虑软限制和硬限制ulimit -s),则尽管您认为自己都在堆上,但仍会发生段错误(或得到STORAGE_ERROR

为缓解此问题,(尽管在UpperBound是动态的情况下可能无法在每种情况下使用 eg …),您可以使用以下方法编译代码:

  • "-fstack-usage"(获取每个单元的使用信息)
  • "-Wstack-usage=2000"(或根据您的情况更准确的限制,请参见gnat's documentation,以获取更多信息),以警告使用过多堆栈(或堆栈使用量不受限制)的函数。

第二个选项可能已发出警告,并指出堆栈溢出。