为什么这段代码没有通过-Wlifetime触发警告?

时间:2020-11-08 20:21:02

标签: c++ lifetime

我正在阅读lifetime safety core guidelines paper,并渴望在实践中尝试使用using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Pomelo.EntityFrameworkCore.MySql.Infrastructure; namespace IssueConsoleTemplate { // // EF Core Entities: // public sealed class SearchContact { public Guid IdContact { get; set; } public string FirstName { get; set; } public IEnumerable<SearchContactsNumber> Numbers { get; set; } } // // JSON Entities: // public sealed class SearchContactsNumber { public Guid IdNumber { get; set; } public string Type { get; set; } public string Number { get; set; } } // // DbContext: // public class Context : DbContext { public DbSet<SearchContact> SearchContacts { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseMySql( "server=127.0.0.1;port=3306;user=root;password=;database=So64741089", b => b.ServerVersion("8.0.21-mysql") .CharSetBehavior(CharSetBehavior.NeverAppend) .UseMicrosoftJson()) // <-- needed when using the Microsoft JSON stack (System.Text.Json) .UseLoggerFactory( LoggerFactory.Create( b => b .AddConsole() .AddFilter(level => level >= LogLevel.Information))) .EnableSensitiveDataLogging() .EnableDetailedErrors(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<SearchContact>( entity => { entity.HasKey(e => e.IdContact); entity.Property(e => e.Numbers) .HasColumnType("json"); // <-- simple way to serialize any property from/to JSON }); } } internal class Program { private static void Main() { using var context = new Context(); SetupDatabase(context); var searchContacts = context.SearchContacts .FromSqlInterpolated($"CALL `SearchContacts`()") .ToList(); Debug.Assert(searchContacts.Count == 1); Debug.Assert(searchContacts[0].Numbers.Count() == 1); Debug.Assert(searchContacts[0].Numbers.First().IdNumber == new Guid("481d2957-21da-11eb-a249-de3268ec1e72")); } private static void SetupDatabase(Context context) { context.Database.EnsureDeleted(); context.Database.EnsureCreated(); var connection = context.Database.GetDbConnection(); connection.Open(); using var command = connection.CreateCommand(); command.CommandText = @"CREATE PROCEDURE `SearchContacts`() BEGIN SELECT '34f8d20f-21da-11eb-a249-de3268ec1e72' as `IdContact`, 'Paul' as `FirstName`, '[{""IdNumber"":""481d2957-21da-11eb-a249-de3268ec1e72"",""Type"":""Telephone"",""Number"":""+440001122333""}]' as `Numbers`; END"; command.ExecuteNonQuery(); } } } 标志。首先,我写了以下简单示例:

-Wlifetime

它确实会发出一些警告,但是显然它们出现在stdlib中,并且与我的代码无关:

class Wrapper
{
public:
    Wrapper(std::string s)
        : str_(std::move(s))
    { }

    const std::string& GetString() const
    {
        return str_;
    }

private:
    std::string str_;
};

const std::string& example() {
    return Wrapper("abc").GetString();
}

(无论我写什么代码,这些警告仍然存在,因此我认为它们无关紧要)

我对代码中缺少警告感到惊讶。据我所知,返回的字符串的生存期应为In file included from <built-in>:1: /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3233:38: warning: returning a pointer with points-to set (*(*this).m_first) where points-to set ((null), **this) is expected [-Wlifetime] consteval iterator begin() const { return m_first; } ^~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3235:36: warning: returning a pointer with points-to set (*(*this).m_last) where points-to set ((null), **this) is expected [-Wlifetime] consteval iterator end() const { return m_last; } ^~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3263:3: warning: returning a dangling pointer [-Wlifetime] return range(reflection, pred); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3276:10: note: in instantiation of function template specialization 'std::experimental::meta::v1::members_of<std::experimental::meta::v1::detail::always_true_fn>' requested here return members_of(reflection, detail::always_true); ^ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3263:10: note: it was never initialized here return range(reflection, pred); ^~~~~~~~~~~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3281:3: warning: returning a dangling pointer [-Wlifetime] return param_range(reflection); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3281:10: note: it was never initialized here return param_range(reflection); ^~~~~~~~~~~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3289:3: warning: returning a dangling pointer [-Wlifetime] return __reflect(detail::query_get_begin, reflection); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3289:10: note: it was never initialized here return __reflect(detail::query_get_begin, reflection); ,因为它是Wrapper的隐式参数(1.1.4:“默认情况下,我们假定函数返回的值源自其参数”)。我什至在类定义中添加了Wrapper::GetString,但是没有运气。

Godbolt example with -Wlifetime enabled

为什么我的代码没有产生警告,并且在这种情况下有什么方法可以使静态分析正常工作?

0 个答案:

没有答案