mirror of
https://github.com/apache/arrow.git
synced 2026-10-29 17:15:39 +08:00
### Rationale for this change Now that we have a general security model for the Arrow specs, add a security model for Arrow C++ specifically, meant to describe appropriate API usage. ### Are these changes tested? N/A. ### Are there any user-facing changes? No. * GitHub Issue: #49274 Authored-by: Antoine Pitrou <antoine@python.org> Signed-off-by: Antoine Pitrou <antoine@python.org>
113 lines
3.8 KiB
ReStructuredText
113 lines
3.8 KiB
ReStructuredText
.. Licensed to the Apache Software Foundation (ASF) under one
|
|
.. or more contributor license agreements. See the NOTICE file
|
|
.. distributed with this work for additional information
|
|
.. regarding copyright ownership. The ASF licenses this file
|
|
.. to you under the Apache License, Version 2.0 (the
|
|
.. "License"); you may not use this file except in compliance
|
|
.. with the License. You may obtain a copy of the License at
|
|
|
|
.. http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
.. Unless required by applicable law or agreed to in writing,
|
|
.. software distributed under the License is distributed on an
|
|
.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
.. KIND, either express or implied. See the License for the
|
|
.. specific language governing permissions and limitations
|
|
.. under the License.
|
|
|
|
.. default-domain:: cpp
|
|
.. highlight:: cpp
|
|
|
|
.. cpp:namespace:: arrow
|
|
|
|
.. _cpp-conventions:
|
|
|
|
Conventions
|
|
===========
|
|
|
|
The Arrow C++ API follows a few simple guidelines. As with many rules,
|
|
there may be exceptions.
|
|
|
|
Language version
|
|
----------------
|
|
|
|
Starting with version 23.0, Arrow C++ requires C++20 or later.
|
|
|
|
Namespacing
|
|
-----------
|
|
|
|
All the Arrow API (except macros) is namespaced inside a ``arrow`` namespace,
|
|
and nested namespaces thereof.
|
|
|
|
Safe pointers
|
|
-------------
|
|
|
|
Arrow objects are usually passed and stored using safe pointers -- most of
|
|
the time :class:`std::shared_ptr` but sometimes also :class:`std::unique_ptr`.
|
|
|
|
Non-owning alternatives exist for the rare situations where the overhead of
|
|
a safe pointer is considered unacceptable: :class:`ArraySpan` and :class:`BufferSpan`.
|
|
Their usage in third-party code is not recommended.
|
|
|
|
Immutability
|
|
------------
|
|
|
|
Many Arrow objects are immutable: once constructed, their logical properties
|
|
cannot change anymore. This makes it possible to use them in multi-threaded
|
|
scenarios without requiring tedious and error-prone synchronization.
|
|
|
|
There are obvious exceptions to this, such as IO objects or mutable data buffers.
|
|
|
|
Error reporting
|
|
---------------
|
|
|
|
Most APIs indicate a successful or erroneous outcome by returning a
|
|
:class:`arrow::Status` instance. Arrow doesn't throw exceptions of its
|
|
own, but third-party exceptions might propagate through, especially
|
|
:class:`std::bad_alloc` (but Arrow doesn't use the standard allocators for
|
|
large data).
|
|
|
|
When an API can return either an error code or a successful value, it usually
|
|
does so by returning the template class
|
|
:class:`arrow::Result <template\<class T\> arrow::Result>`. However,
|
|
some APIs (usually deprecated) return :class:`arrow::Status` and pass the
|
|
result value as an out-pointer parameter.
|
|
|
|
Here is an example of checking the outcome of an operation::
|
|
|
|
const int64_t buffer_size = 4096;
|
|
|
|
auto maybe_buffer = arrow::AllocateBuffer(buffer_size, &buffer);
|
|
if (!maybe_buffer.ok()) {
|
|
// ... handle error
|
|
} else {
|
|
std::shared_ptr<arrow::Buffer> buffer = *maybe_buffer;
|
|
// ... use allocated buffer
|
|
}
|
|
|
|
If the caller function itself returns a :class:`arrow::Result` or
|
|
:class:`arrow::Status` and wants to propagate any non-successful outcome, two
|
|
convenience macros are available:
|
|
|
|
* :c:macro:`ARROW_RETURN_NOT_OK` takes a :class:`arrow::Status` parameter
|
|
and returns it if not successful.
|
|
|
|
* :c:macro:`ARROW_ASSIGN_OR_RAISE` takes a :class:`arrow::Result` parameter,
|
|
assigns its result to a *lvalue* if successful, or returns the corresponding
|
|
:class:`arrow::Status` on error.
|
|
|
|
For example::
|
|
|
|
arrow::Status DoSomething() {
|
|
const int64_t buffer_size = 4096;
|
|
std::shared_ptr<arrow::Buffer> buffer;
|
|
ARROW_ASSIGN_OR_RAISE(buffer, arrow::AllocateBuffer(buffer_size));
|
|
// ... allocation successful, do something with buffer below
|
|
|
|
// return success at the end
|
|
return Status::OK();
|
|
}
|
|
|
|
.. seealso::
|
|
:doc:`API reference for error reporting <api/support>`
|